Sinon: 使用多个 .withArgs 链接 sinon.stub() 仅存根最后的声明

创建于 2012-09-25  ·  23评论  ·  资料来源: sinonjs/sinon

使用多个 .withArgs 链接 sinon.stub() 仅存根最后的声明

var stubbedFunction = sinon.stub().withArgs(argument1).returns(value1).withArgs(argument2).returns(value2);

那么实际上只有最后一个声明 (.withArgs(argument2).returns(value2)) 被存根

最有用的评论

这适用于 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

所有23条评论

需要使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

  • 节点 6.9.4
  • NPM 3.10.10

这么晚才回复很抱歉

@zurfyx我已经尝试使用您提到的配置进行复制,使用与我上面编写的相同代码,它按预期输出到控制台sleepyeating 。 不知道为什么它会导致你的问题😢

@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)放在第一个位置即可解决问题

此页面是否有帮助?
0 / 5 - 0 等级