描述错误
将Sinon升级到最新的v7版本会导致一些意外的故障。 我能够识别的唯一相关更改是此PR:#1955-将deep-equal.js
替换samsam.deepEqual
。
测试可以通过7.2.0之前的所有版本,恢复到7.1.1(一个发行版)不会导致任何问题,并且所有测试都可以通过。
观察到错误:
AssertionError: expected addTracks to have been called with arguments [{ language: "en", trackContentType: "CEA608" }]
[[functionStub] { language: "en", trackContentType: "CEA608" }] [{ language: "en", trackContentType: "CEA608" }]
测试产生错误:
it('should call getTextTracksManager, Track, and setCaptionLang', () => {
sinonSandbox.stub(chromecastReceiver, 'setCaptionLang');
chromecastReceiver.player.getTextTracksManager = sinonSandbox.stub()
.returns({ addTracks: sinonSandbox.spy() });
sinonSandbox.stub(cast.framework.messages, 'Track').returns(() => ({}));
chromecastReceiver.loadCaptions('off');
expect(chromecastReceiver.player.getTextTracksManager).to.have.callCount(1);
expect(cast.framework.messages.Track).to.have.been
.calledWith(3, cast.framework.messages.TrackType.TEXT);
expect(chromecastReceiver.textTracksManager.addTracks).to.have.been.calledWith([{
trackContentType: cast.framework.messages.CaptionMimeType.CEA608,
language: 'en',
}]);
expect(chromecastReceiver.setCaptionLang).to.have.been.calledWith('off');
});
重现
重现行为的步骤:
预期行为
测试应该通过
屏幕截图
如果适用,请添加屏幕截图以帮助解释您的问题。
上下文(请完成以下信息):
请让我知道是否可以提供有关此的更多信息。
感谢您提供的错误报告。 但是,它有一个主要缺陷:我无法运行您的示例进行验证或跟踪错误! 它本身不能运行,并且没有复制的方法,很难解决。
您能为繁殖做一个最低限度的候选人吗? 您不必复制整个原始示例,更像是像var myObject = { aMethod: function(){}, aProp: 42 }; // etc
这样的简化。
如果我们知道这是失败的,那么我们当然会升级主要版本,因此回归测试将是很棒的!
PS似乎也涉及sinon-chai
。 值得列出。
@ fatso83让我看看如何获得一个孤立的,可运行的示例进行复制
任何更新?
由于此问题最近没有活动,因此已被自动标记为陈旧。 如果没有其他活动发生,它将关闭。 感谢你的贡献。
@mantoni您是否没有报告在您的一个项目中遇到过类似情况?
抱歉,由于缺少更新,我不再与包含该问题的项目相关联。 如果其他任何人都可以遇到相同的问题,那么如果他们可以提供一个例子来进行复制,那将是很好的。
@ fatso83我不记得遇到过同样的问题。 我已经在几个项目中升级到最新的Sinon,没有任何问题。
由于无法复制而结束
很抱歉让这个问题从死里复活,但是我遇到了同样的问题。
_下面的代码已简化,以用于说明目的。_
在我的应用程序中,我有这个课程
class MyUser {
// ... some user properties
}
以后我会在像这样的Koa控制器函数中使用它
const mqClient = require('./mqClient');
// GET /userDetails/<id> endpoint
async function getUserDetailsController(req, res) {
const user = new MyUser();
// populate user with properties etc.
user.id = '1';
user.name = 'Hans Gruber';
user.tasks = [{ id: '42', title: 'execute Nakatomi tower heist' }];
// ... get more details ...
// Notify other users about this user
mqClient.notifyOthers(user);
res.json({ ok: true, user });
}
在我的getUserDetailsController.test.js
我做这样的事情:
const mqClient = require('./mqClient');
const createExpectedUser = overrides => {
id: '1',
name: 'Hans Gruber',
tasks: [{ id: '42', title: 'execute Nakatomi tower heist' }],
...overrides
};
it('does not fail', async () => {
sinon.spy(mqClient, 'notifyOthers');
const expectedUser = createExpectedUser();
await presetRequest // helper object to run the controller code
.get('/userDetails/1')
.expect(200);
// This works with sinon 7.1.1.
// This fails with sinon 7.2.0 and onwards.
sinon.assert.calledWithMatch(mqClient.notifyOthers, expectedUser);
});
我使用sinon 7.1.1(使用samsam
“ 2.1.3”)进行了测试,并且可以正常工作。
版本7.2.0失败(使用samsam
3.3.3)。
最新版本9.2.3也会失败(使用samsam
5.3.0)。
我在节点14.5.3上,但是这也在节点12.20.0上发生。
我通过手动比较user
来比较控制器中的expectedUser
和测试中的JSON.stringify
,它们是100%相等的。 从句法上唯一的区别是,控制器使用类,而测试使用对象文字。
有谁知道为什么会这样? 还是有人对如何解决这个问题有个好主意?
亲切的问候,
丹尼尔
恐怕只要我们没有可重复的案例来验证这一点,我们就无法证明我们有空闲时间来研究这个问题。 我没有什么可寻找的,也没有任何东西可以证明我是对的。
不过,我确实喜欢修复错误,因此,如果您可以花一些时间来尝试使我可以运行的东西,那就这样做吧! RunKit是执行此操作的出色服务: https ://runkit.com/fatso83/sinon-issue-reproducible-bug-template
嗨@ fatso83 ,
感谢您抽出宝贵的时间对此进行调查。 我按照您的要求进行了操作,并创建了一个可显示错误的Runkit演示。 只需注释/取消注释不同的require('sinon')
语句,然后运行代码以查看错误。
https://runkit.com/danielkg/sinon-issue-reproducible-bug-template
我也将代码发布在这里,以防runkit由于任何原因而无法正常工作。
// Employs 'mini-mocha' to emulate running in the Mocha test runner (mochajs.org)
require("@fatso83/mini-mocha").install();
// const sinon = require('[email protected]'); // WORKS!
const sinon = require('[email protected]'); // FAILS!
// const sinon = require('sinon'); // FAILS!
const { assert } = require('@sinonjs/referee');
const SAMPLE_USER = {
id: 1,
name: 'Kid',
age: 22,
weight: 83.5,
notes: [{ txt: 'abc' }, { txt: 'def' }, { txt: 'ghi' }],
};
class MyUser {
constructor(id, name, age, weight, notes = []) {
this.id = id;
this.name = name;
this.age = age;
this.weight = weight;
this.notes = notes;
}
}
const createFakeUser = overrides => ({
id: '007',
name: 'Bond',
...overrides,
});
class Talkie {
talk(user, topic) {
console.log('talked to', user.name, 'about', topic);
}
}
const action = (userId, talkie) => {
const { name, age, weight, notes } = SAMPLE_USER;
const user = new MyUser(userId, name, age, weight, notes);
talkie.talk(user, 'apples');
return user;
}
describe('stubbing', () => {
const talkie = new Talkie();
afterEach(() => {
sinon.restore();
});
beforeEach(() => {
sinon.spy(talkie, 'talk');
});
it('is the same user', () => {
const userA = action(1, talkie);
const userB = createFakeUser(SAMPLE_USER);
assert.equals(JSON.stringify(userA), JSON.stringify(userB));
});
it('should set the return value', () => {
const userA = action(1, talkie);
const userB = createFakeUser(SAMPLE_USER);
sinon.assert.calledWith(talkie.talk, userB, sinon.match.string);
});
});
如果您有时间,请再看一下。 谢谢你。
亲切的问候,
丹尼尔
最有用的评论
嗨@ fatso83 ,
感谢您抽出宝贵的时间对此进行调查。 我按照您的要求进行了操作,并创建了一个可显示错误的Runkit演示。 只需注释/取消注释不同的
require('sinon')
语句,然后运行代码以查看错误。https://runkit.com/danielkg/sinon-issue-reproducible-bug-template
我也将代码发布在这里,以防runkit由于任何原因而无法正常工作。
如果您有时间,请再看一下。 谢谢你。
亲切的问候,
丹尼尔