单元测试和 spy 、 stub 和模拟的概念的新手。
我想从下面的代码中测试 password.js 中的 verify 方法,但是我无法 stub hash 测试文件中的函数。
因为 verify 使用了 hash 函数并且导出了 hash 函数,所以我应该 stub hash 函数返回固定响应而不是实际调用的 hash。因为我不想测试 hash 函数。
问题:在测试verify时没有调用为hash函数创建的stub。
附带问题 1:我应该专注于测试函数本身的逻辑而不是其他被调用函数的逻辑吗?
主要问题:(已回答)如何 stub 在同一模块中调用的模块函数?
附带问题 2:如果 hash 未导出但仅保留在模块中,我将如何 stub ?
密码.js
/**
* Creates a hash based on a salt from a given password
* if there is no salt a new salt will be generated
*
* @param {String} password
* @param {String} [salt] Optional value, if not given will generate a salt
*/
function hash (password, salt) {
// returns a promise that resolves an hash object with hash and salt key
// example: {hash: '2512521nska...', salt: '25hbBhhsfa...'}
}
/**
* Verifies if a password matches a hash by hashing the password
* with a given salt
*
* @param {String} password
* @param {String} hashString
* @param {String} salt
*/
function verify (password, hashString, salt) {
return hash(password, salt)
.then((res) => res.hash === hashString);
}
module.exports = {hash, verify};
password.test.js
import test from 'ava';
import sinon from 'sinon';
import passwordModule from './password';
test('verify - should verify password', function * (t) {
const password = 'test-password';
const salt = null;
const hash = 'my-hash';
const hashStub = sinon.stub(passwordModule, 'hash', (password, salt) => Promise.resolve({hash, salt}));
const verified = yield passwordModule.verify(password, hash, salt);
t.true(verified);
hashStub.restore();
});
Tests and the modules are transpilled with babel. But the module isn't using ES6 module exports as it is used in node env without transpilling.
I'm transpilling all code during testing so that it is future proof and the save env can be used for both frontend and backend code, where the frontend code is transpilled.
最佳答案
Side question 1: Should I be focusing on testing the logic of the function itself rather the other called functions?
测试 verify 的一部分是确保它正确调用 hash。同样在更一般的意义上,并不太适用于您的代码,一个函数应该正确处理其他函数抛出的错误。在您的情况下,您将任何错误传播给 verify 的调用者,这就是它实际上并不适用的原因。
Main Question: How do stub a module function that is called within the same module?
您已经找到了答案,但请参阅下面的备选方案。
Side question 2: How would I go about stubbing hash if it where not exported but stayed only within the module?
一个很好的模块是 rewire ,它允许您覆盖模块内的私有(private)(非导出)变量。它还将有助于解决您的“主要问题”,因为它允许您像以前一样保留代码。
这是你在 rewire 上的测试:
import test from 'ava';
import sinon from 'sinon';
import rewire from 'rewire';
const passwordModule = rewire('./password');
test('verify - should verify password', function * (t) {
const password = 'test-password';
const salt = null;
const hash = 'my-hash';
let hashStub = sinon.stub().returns(Promise.resolve({hash, salt}));
// Replace the `hash` function inside your module with the stub.
let revert = passwordModule.__set__('hash', hashStub);
const verified = yield passwordModule.verify(password, hash, salt);
t.true(verified);
// Revert to the original `hash` function.
revert();
});
关于javascript - 模拟在同一模块中导出和调用的模块函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37686646/
假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于
作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代
我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah
设置:狂欢ruby1.9.2高线(1.6.13)描述:我已经相当习惯在其他一些项目中使用highline,但已经有几个月没有使用它了。现在,在Ruby1.9.2上全新安装时,它似乎不允许在同一行回答提示。所以以前我会看到类似的东西:require"highline/import"ask"Whatisyourfavoritecolor?"并得到:Whatisyourfavoritecolor?|现在我看到类似的东西:Whatisyourfavoritecolor?|竖线(|)符号是我的终端光标。知道为什么会发生这种变化吗? 最佳答案
是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我正在尝试用ruby中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了
我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file
我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin
我刚刚被困在这个问题上一段时间了。以这个基地为例:moduleTopclassTestendmoduleFooendend稍后,我可以通过这样做在Foo中定义扩展Test的类:moduleTopmoduleFooclassSomeTest但是,如果我尝试通过使用::指定模块来最小化缩进:moduleTop::FooclassFailure这失败了:NameError:uninitializedconstantTop::Foo::Test这是一个错误,还是仅仅是Ruby解析变量名的方式的逻辑结果? 最佳答案 Isthisabug,or