如何使用 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;
})