如何模拟在函数内部调用的Karma单元测试中的承诺

时间:2017-07-19 11:50:57

标签: javascript angularjs unit-testing karma-jasmine

我的Angular控制器中有以下函数,如果promise返回预期结果,则需要测试

    function getName() {
      var name = "";
      nameService.getName().then(function (data) {
        name = data.name;
      });
      return name;
    }

如何使用虚假数据模拟承诺调用?我不确定我是否可以在这里使用$ httpBackend或$ provide?我试过了,但它没有工作:

it("function getName should get the name from the nameService.getNameInfo function", function () {
        var name = { name: "name1"};
        spyOn(mockNameService, 'getNameInfo').and.callFake(function() {
            return {
                then: function(callback) {return callback(name);}
            };
        });
        var result = myCtrl.getName();
        expect(result).toEqual("name1");
    });

2 个答案:

答案 0 :(得分:0)

尝试使用:

spyOn(mockNameService, 'getNameInfo').and.returns($q.when('dummyData'));

模拟您的数据。 然后,您需要在解决后进行验证。所以写:

expect(myCtrl.getName().then(function(name){
    expect(name).toBe('dummyData');
}).toBeResolved();

答案 1 :(得分:0)

问题不在于您的单元测试代码,而是在所有应用程序代码中的错误实现。 这里:

function getName() {
      var name = "";
      nameService.getName().then(function (data) {
        name = data.name;
      });
      return name; //it will return "" because the promise yet not resolved
    }

在此代码中,函数getName将始终返回空字符串"",并且当promise解析name = data.name时,它将永远不会返回您分配的值,因为promise是异步的,因此时间解析函数getName已经将空字符串返回给调用者! 所以,在这种情况下,重构原始代码并在那里修复它应该是第一个想法!

实际上您的单元测试代码已经识别出代码中的错误,因此它已经服务于其原始目的,测试用例失败并不总是意味着您必须在那里修复它,而不是您的测试用例是完全针对所有可能的单元/模块的逻辑期望,你需要考虑它失败的原因,查看实际的代码,这是编写单元测试用例的实际目的