我无法存根要在打字稿中测试的方法所使用的方法。为了清楚起见,我在示例中删除了很多方法本身,但是基本上我有一个getServiceWithRetry
方法来调用getService
方法。
即。
export function getServiceWithRetry(name:string, triesLeft:number) {
//do stuff
getService(name)
//do more stuff
}
export function getService(name:string) {
//lookup stuff
}
这作为
Lookup
导入到我的测试中。如果在测试中调用getService
,则可以成功存出getService方法,但是,当我运行getServiceWithRetry
时,它将调用实际的getService
方法而不是存根。有人知道我在做什么错吗?it("test", function(done) {
let serviceStub = sinon.stub(Lookup, 'getService')
serviceStub.returns(Promise.resolve("resolved"))
//this uses the stub
Lookup.getService("name").then(function(value) {
console.log("success: "+value)
}, function(error) {
console.log("error: "+error)
})
//this calls the actual method, not the stub as I would expect it to
Lookup.getServiceWithRetry("serviceName", 4).then(function(value) {
console.log("success: "+value)
}, function(error) {
console.log("error: "+error)
})
done()
})
注意:对于不熟悉蓝鸟诺言的人,
.then(function(value){}, function(error){})
方法处理如果诺言成功和诺言被拒绝的情况。 最佳答案
问题在于,使用sinon.stub(Lookup, 'getService')
会使您在测试中持有的Lookup变量的内部发生变异,然后从该变量获取方法。在您的Lookup模块中,该函数只是直接从其本地范围中查找getService
。从外部看,我认为您没有办法弄乱该示波器,因此恐怕没有简单的魔术解决方案。
通常,您通常无法在测试中很好地模拟单个模块的各个部分。您需要对此进行一些重组,并且有一些选择:
完全分别测试它们。将getServiceWithRetry更改为通用的retry
方法,例如因此您可以像retry(nTimes, getService, "serviceName")
或retry(() => getService("serviceName"), nTimes)
这样称呼它。如果这样做是可行的(即,如果它与getService
的联系不太紧密),则可以轻松地自己进行测试:
var myStub = sinon.stub();
myStub.onCall(0).throw("fail once");
myStub.onCall(0).throw("fail twice");
myStub.returns(true); // then return happily
expect(retry(myStub, 1)).to.throw("fail twice"); // gives up after one retry
expect(retry(myStub, 5)).to.return(true); // keeps going to success
如果希望在其他地方仅调用一个getServiceWithRetry,则可以轻松构建一个:
var getServiceWithRetry = (arg, triesLeft) => retry(getService, tries)
放弃,一起测试。这意味着存根
getService
依赖的内容,而不是直接存根。这取决于您要从测试中获得的粒度级别,但是如果此代码很简单并且可以进行更粗略的测试,则这可能是一个简单的选择。即使您仍然将它们分开,您也可能希望这样做,以获得单元和集成测试以获得额外的覆盖范围。如果它们之间存在一些更复杂的交互,则这是双重事实。
从我所看到的情况来看,在这种情况下可能不相关,但在其他情况下,则有点像将待测方法(getServiceWithRetry)放在类中,并使用依赖项注入。您将创建一个类,该类在其构造函数中使用依赖项(getService方法),将其存储在内部,然后在以后对结果对象调用方法时使用它。在生产代码中,必须使用其他方法将它们正确粘合在一起,然后才能在测试中通过存根传递。
对于这种情况,我也期望过高,但是您可以将
getService
拉入Lookup导入的完全独立的模块中,并在测试过程中使用Rewire之类的东西将其替换为其他模块。这实际上与依赖项注入选项非常相似,它使您的生产代码更简单,但以使您的测试代码更复杂和神奇为代价。
关于javascript - Sinon-如何对要测试的方法调用的方法进行 stub ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39988909/