如何使用 Jasmine 模拟链式承诺?
How to mock chained promises using Jasmine?
我正在为包含这段代码的方法编写单元测试:
Name.get($scope.nameId).then(function(name){
Return name;
}).then(doSomething);
function doSomething(name)
看起来像这样。
function doSomething(name){
addNametoList(name);
}
我不需要测试这部分代码。因为我不能在我的测试中忽略它(或者我可以吗?),我需要模拟它。我嘲笑了第一个承诺
spyOn(mockName, 'get').and.returnValues($q.resolve({"Mike"}));
并认为它会通过第二个 then(doSomething)
传播,但 name
在函数 addNametoList
中是 undefined
。
我想我也必须模拟 doSomething
但我不知道如何将它们链接在一起。
I don't need to test this part of the code. Since I can't just ignore
it in my test (or can I?), I need to mock it. I mocked the first
promise
IMO,没有必要对这些设置进行整体测试。
单独测试每个单元。
例如
A = () => {
...
}
B = () => {
...
}
C = () => {
...
}
现在我们有 F,它调用 A B & C
F = () => A(B(C))
或者你的情况
F = () => A().then(B).then(C)
我们可以测试 F,但它需要一些设置,而且很脆弱。
最好测试 A、B 和 C(为 F 提供适当的覆盖率)并忽略 F。
您的(部分)控制器代码
$scope.list = [];
function addNameToList(name) {
$scope.list.push(name);
}
function doSomething(name){
addNametoList(name);
}
$scope.functionToTest = function() {
Name.get($scope.nameId).then(function(name){
return name;
}).then(doSomething);
};
你的测试
it('should add the name to the list when Name.get() is resolved', function() {
// Arrange
var getDeferred = $q.defer();
spyOn(mockName, 'get').and.returnValue(getDeferred.promise);
// Act
$scope.functionToTest();
getDeferred.resolve('some name that should be in the list');
$scope.$apply();
// Assert
expect($scope.list).toEqual(['some name that should be in the list']);
});
评论
请注意,您的代码的以下部分没有任何作用,可以删除而不影响任何内容。
.then(function(name){
return name;
})
我正在为包含这段代码的方法编写单元测试:
Name.get($scope.nameId).then(function(name){
Return name;
}).then(doSomething);
function doSomething(name)
看起来像这样。
function doSomething(name){
addNametoList(name);
}
我不需要测试这部分代码。因为我不能在我的测试中忽略它(或者我可以吗?),我需要模拟它。我嘲笑了第一个承诺
spyOn(mockName, 'get').and.returnValues($q.resolve({"Mike"}));
并认为它会通过第二个 then(doSomething)
传播,但 name
在函数 addNametoList
中是 undefined
。
我想我也必须模拟 doSomething
但我不知道如何将它们链接在一起。
I don't need to test this part of the code. Since I can't just ignore it in my test (or can I?), I need to mock it. I mocked the first promise
IMO,没有必要对这些设置进行整体测试。 单独测试每个单元。
例如
A = () => {
...
}
B = () => {
...
}
C = () => {
...
}
现在我们有 F,它调用 A B & C
F = () => A(B(C))
或者你的情况
F = () => A().then(B).then(C)
我们可以测试 F,但它需要一些设置,而且很脆弱。 最好测试 A、B 和 C(为 F 提供适当的覆盖率)并忽略 F。
您的(部分)控制器代码
$scope.list = [];
function addNameToList(name) {
$scope.list.push(name);
}
function doSomething(name){
addNametoList(name);
}
$scope.functionToTest = function() {
Name.get($scope.nameId).then(function(name){
return name;
}).then(doSomething);
};
你的测试
it('should add the name to the list when Name.get() is resolved', function() {
// Arrange
var getDeferred = $q.defer();
spyOn(mockName, 'get').and.returnValue(getDeferred.promise);
// Act
$scope.functionToTest();
getDeferred.resolve('some name that should be in the list');
$scope.$apply();
// Assert
expect($scope.list).toEqual(['some name that should be in the list']);
});
评论
请注意,您的代码的以下部分没有任何作用,可以删除而不影响任何内容。
.then(function(name){
return name;
})