使用多个 .withArgs 链接 sinon.stub() 仅存根最后的声明
var stubbedFunction = sinon.stub().withArgs(argument1).returns(value1).withArgs(argument2).returns(value2);
那么实际上只有最后一个声明 (.withArgs(argument2).returns(value2)) 被存根
需要使withArgs
修改并返回创建它的原始存根(如果可用)。
+1 为此。 在相关说明中,我希望withArgs
可以选择允许传递给不匹配参数的原始方法。
例如,如果我想存根 Node.js 的fs.readFileSync()
方法,我希望 Sinon 保留原始实现,以便require()
(使用readFileSync
)不会被破坏,但对我的测试使用特定文件的存根方法。
上一条评论的示例:
beforeEach(function() {
global.fs = require('fs');
sinon.stub(fs, 'readFileSync').onlyWithArgs('my-file.txt').returns('Contents of file');
// Then require the module under test, which uses fs.readFileSync() internally
// require() uses original method with correct calling context
global.myModule = require('../src/my-module');
});
afterEach(function() {
fs.readFileSync.restore();
});
it('does something with the file', function() {
expect(myModule.loadFromFile()).toEqual('Contents of file');
});
我想建议@froots上面的帖子张贴在文档的某个地方。 我搜索了很长时间才找到关于如何通过require
模拟包含其他依赖项的文件的解决方案
好主意。 想试一试吗? http://github.com/cjohansen/sinon-web/
这适用于 Sinon 1.7.3:
var s = sinon.stub();
s.withArgs(1).returns('a');
s.withArgs(2).returns('b');
s(1); // -> 'a'
s(2); // -> 'b'
s(3) // -> undefined
我不认为这是它工作的一个例子,因为它仍然没有链接(你必须使用原始的存根/模拟)。
真的。 但这已经足够好了,它清楚地表明了正在发生的事情。 链接为解释留下了空间。
我同意@mantoni。 存根的目的是指示服务/查询的合同响应。 这种风格更好地表达了这一点。
我认为这里的文档可能会有所改进。
我期待以下工作:
var someObj = {
someProp: sinon.stub().withArgs("foo").returns(true)
}
它显然没有按预期工作。 但是,更重要的是,它没有正确失败。 当foo
没有提供时 $ someObj.someProp
没有返回 true ,它总是返回true
。 由于returns
子句返回一个 Behavior 实例,因此someObj.someProp
尽职尽责地返回true
,而不管输入如何。
我理解返回不同类型对象的链接结构背后的基本原理。 但是用户被误导了那些返回的对象是什么。 由于 CallObjects 和 Behaviors 公开的方法与 Stubs 提供的 API 相匹配,因此很容易理解为什么人们会认为它们是 stubs。
我同意@jasonkarns。 我刚刚落入了同样的“陷阱”:内联存根声明不会返回预期的存根实例。 但是,使用模拟时,链接似乎可以按预期工作:
var someObj = {
someProp: sinon.mock().withArgs("foo").returns(true)
}
这有什么原因吗?
不确定我是否遗漏了什么,但@froots点现在可能吗? 不得不这样做:
sinon.stub(fs, 'readdirSync', (dir) => {
if (dir === 'foo-path') {
return [
'my.js',
'fake.js',
'stuff.js'
];
}
return fsReaddir(dir);
});
想做类似的事情:
var myStub = sinon.stub(fs, 'readdirSync', fs.readdirSync);
myStub
.withArgs('foo-path')
.returns([
'my.js',
'fake.js',
'stuff.js'
]);
我认为这个问题现在已经解决了,下面的示例可以按预期使用[email protected]
var Dummy = {
doSomething: function(something) {
return 'doing ...' + something;
}
}
sinon.stub(Dummy, 'doSomething')
.withArgs('sleep').returns('sleepy')
.withArgs('eat').returns('eating');
console.log(Dummy.doSomething('sleep'));
console.log(Dummy.doSomething('eat'));
@valentin-radulescu-hs 它仍然在我这边失败了1.17.7
。
它仍然将最新的returns
作为唯一的返回值,不管withArgs
(正如@jasonkarns https://github.com/sinonjs/sinon/issues/176#issuecomment-所指出的那样78191790)。
对我有用的是@mantoni的答案https://github.com/sinonjs/sinon/issues/176#issuecomment -33636496,不链接withArgs()
。
var s = sinon.stub();
s.withArgs(1).returns('a');
s.withArgs(2).returns('b');
@zurfyx您是在节点上还是在浏览器中运行? 您使用的是哪个版本的节点/浏览器? 不确定这是否重要,但我想尝试并最终复制。
嘿@valentin-radulescu-hs。 我在 Node 上运行它,使用babel-cli
6.22.2
这么晚才回复很抱歉
@zurfyx我已经尝试使用您提到的配置进行复制,使用与我上面编写的相同代码,它按预期输出到控制台sleepy
和eating
。 不知道为什么它会导致你的问题😢
@zurfyx只是_完全_确定,你试过这个吗?
grep version node_modules/sinon/package.json
rm -r node_modules
rm npm-shrinkwrap
npm install
grep version node_modules/sinon/package.json
大多数时候我遇到问题是由于我期望的软件包版本与安装的不同。
@fatso83它也不起作用。 grep
输出版本仍然是1.1.7.7
。
这是我的完整测试,以防万一:
it('test', () => {
const s = sinon.stub();
s.withArgs('a').returns('1');
s.withArgs('b').returns('2');
console.info(s('c'));
});
s('a')
: '1'
✓
s('b')
: '2'
✓
s('c')
: undefined
✓
it('test', () => {
const s = sinon.stub()
.withArgs('a').returns('1')
.withArgs('b').returns('2');
console.info(s('c'));
});
s('a')
: '2'
✗
s('b')
: '2'
✓
s('c')
: '2'
✗
我也可以通过使用 sinon.createStubInstance 来重现这种行为。
const stub = sandbox.stub();
const myObj = function(){};
const objOne = sinon.createStubInstance(myObj);
const objTwo = sinon.createStubInstance(myObj);
stub.withArgs(objOne).returns('1');
stub.withArgs(objTwo).returns('2');
console.info(stub(objOne));
console.info(stub(objTwo));
输出:
2
2
我认为 sinon.createStubInstance 应该创建一个新的存根对象。 这是不正确的吗?
我不完全确定这个问题是否属于这个线程,但它肯定与它有关。 在一个带有sinon 1.17.7
的项目中,我曾经链接了几个withArgs
语句,其中最后一个是作为默认值的“grab-all”匹配器。 例如:
const s = sinon.stub();
s.withArgs(1).returns(1)
.withArgs(2).returns(2)
.withArgs(sinon.match.any).returns('my-default-value')
s(1) // 1
s(5) // my-default-value
现在我正在使用4.1.3
并且行为发生了变化,它总是返回my-default-value
。 这是故意的吗? 如果是这样,有没有办法在withArgs
链中定义默认/备用值?
我不认为改变是有意的。 如果你能提供一个修复
回归随意! 我可以使用 got 帮助追踪它发生的位置
责备。
窝人。 15. 一月 2018, 11.13 skrev 大卫·加西亚[email protected] :
我不完全确定这个问题是否属于这个线程,但它
肯定与它有关。 在一个带有 sinon 1.17.7 的项目中我
用于链接多个 withArgs 语句,其中最后一个是
作为默认值的“grab-all”匹配器。 例如:const s = sinon.stub();s.withArgs(1).returns(1)
.withArgs(2).returns(2)
.withArgs(sinon.match.any).returns('my-default-value')
s(1) // 1s(5) // 我的默认值现在我正在使用 4.1.3 并且行为发生了变化,它总是返回
我的默认值。 这是故意的吗? 如果是这样,有没有办法定义一个
withArgs 链中的默认/后备值?—
你收到这个是因为你被提到了。
直接回复此邮件,在 GitHub 上查看
https://github.com/sinonjs/sinon/issues/176#issuecomment-357638653 ,或者静音
线程
https://github.com/notifications/unsubscribe-auth/AAluXMzqALJ0JlAM3hUaiK1SSyca9H74ks5tKyS4gaJpZM4AK2eu
.>
[图片: - ]
卡尔-埃里克·科普森
[图片:https://]about.me/kopseng
https://about.me/kopseng?promo=email_sig&utm_source=email_sig&utm_medium=email_sig&utm_campaign=external_links
@fatso83我已经缩小了范围,显然是故意的。 对我来说,在最后一个withArgs
语句中指定后备感觉更自然,尽管在这种情况下只需切换顺序并将.withArgs(sinon.match.any)
放在第一个位置即可解决问题
最有用的评论
这适用于 Sinon 1.7.3: