简体   繁体   English

在Angular服务中进行$ q承诺的单元测试-Karma,Jasmine

[英]Unit testing $q promise within Angular service - Karma, Jasmine

I am trying to unit test an Angular service with Karma and Jasmine. 我正在尝试与Karma和Jasmine一起对Angular服务进行单元测试。 I'm making I've seen a number of tutorials on how to unit test a service call from a controller, but I wish to unit test within the service itself. 我正在看过许多有关如何对来自控制器的服务调用进行单元测试的教程,但是我希望对服务本身进行单元测试。 UsersService.findById() makes an async call to find an ID within an ID, but I can't figure out how to write a passing test. UsersService.findById()进行异步调用以在ID中查找ID,但是我不知道如何编写通过测试。 I'm close, but I need a little help. 我已经接近了,但是我需要一点帮助。 Here is the function within UsersService 这是UsersService中的函数

users.service.js users.service.js

        Users.findById = function(id){
            var deferred = $q.defer();

            deferred.resolve(userList.find(function(user){
                return user.id == id;
            }));

            return deferred.promise;
        };

Here is the spec: 规格如下:

users.service.spec.js users.service.spec.js

describe("Users Factory", function(){
    var UsersService, $q, $rootScope, $provide, deferred, mockedDeferred;

    var userList = [
        { id: 1, name: "Richard Hendricks", email: "richard@piedpiper.com", phone: 4085550011, pokemon: { isPresent: true, name: "eevee"}, icon: { isPresent: false, name: null} },
        { id: 2, name: "Erlich Bachman", email: "erlich@aviato.com", phone: 4155552233, pokemon: { isPresent: true, name: "celebi"}, icon: { isPresent: false, name: null} },
        { id: 3, name: "Gavin Belson", email: "gavin@hooli.com", phone: 9165554455, pokemon: { isPresent: true, name: "snorlax"}, icon: { isPresent: false, name: null} }
    ];

    var singleUser = { id: 2, name: "Erlich Bachman", email: "erlich@aviato.com", phone: 4155552233, pokemon: { isPresent: true, name: "celebi"}, icon: { isPresent: false, name: null} };

    function mockQ(){
        deferred = $q.defer();
        spyOn(UsersService, "findById");
        return deferred;
    }

    beforeEach(angular.mock.module("testing_app"));
    beforeEach(angular.mock.module(function(_$provide_){
        $provide = _$provide_;
    }));

    beforeEach(inject(function(_UsersService_, _$q_, _$rootScope_){
        UsersService = _UsersService_;
        $q = _$q_;
        $rootScope = _$rootScope_;
    }));

    describe("Users.findById()", function(){

        beforeEach(function(){
            mockedDeferred = mockQ();
        });

        it("should exist", function(){
            expect(UsersService.findById).toBeDefined();
        });

        it("should equal singleUser", function(){
            UsersService.findById(2);
            deferred.resolve(userList.find(function(user){
                return user.id == 2;
            }));
            expect(UsersService.findById).toHaveBeenCalled();
            expect(deferred.promise).toEqual(singleUser);
        });
    });
});

Here's what I have in my console: 这是控制台中的内容:

埃利希·巴赫曼,这是你妈妈。你不是我的宝贝

I'm close, but how do I get the promise to equal the singleUser variable? 我接近了,但是如何获得等于singleUser变量的承诺?

You are testing the UsersService service. 您正在测试UsersService服务。 Therefore your test cases should exercise the service and verify it behave correctly. 因此,您的测试用例应使用该服务并验证其行为是否正确。 With this in mind checking if findById() as been called on the same function (the test) that call it do not provide any verification and is superfluous and unnecessary. 考虑到这一点,检查是否在调用它的同一个函数(测试)上调用了findById()不会提供任何验证,并且是多余且不必要的。 In this particular test case a more productive check will be to verify that the method return a Promise like object (see here for more info on that). 在这个特定的测试用例中,更有效的检查将是验证该方法是否返回类似Promise的对象(有关更多信息,请参见此处 )。 The other productive check will be to verify the response value (once promise has been resolved) of the method for known inputs. 另一个有效的检查将是验证已知输入方法的响应值(一旦解决了诺言)。 For the latter what you need to do is call $rootScope.$apply(); 对于后者,您需要执行的是$rootScope.$apply(); before checking the resolved value of the promise against the expected one (see the testing section on promise from the angularjs docs for an example on that). 在对照期望的承诺检查解决的价值之前(请参阅angularjs文档中关于promise测试部分,以了解该示例)。 Once we apply this recommendations the tests for findById() will be as follows: 一旦应用了此建议,对findById()的测试将如下所示:

describe("Users.findById()", function(){

    it("should exist", function(){
        expect(UsersService.findById).toBeDefined();
    });

    it("should produce a promise", function(){
        var p = UsersService.findById(2);

        expect(p instanceof $q.resolve().constructor).toBeTruthy();
    });

    it("should equal singleUser", function(){
        var p = UsersService.findById(2), resolvedValue;

        p.then(function(value) { resolvedValue = value; });

        $rootScope.$apply();

        expect(resolvedValue).toEqual(singleUser);
    });
});

On some cases the service under test is more complex and encapsulates other low level services. 在某些情况下,被测服务更为复杂,并封装了其他低层服务。 On those cases you need to spy or mock those lower level services in order to verify that the higher level service under test behaves as expected by checking it calls the lower level services. 在这些情况下,您需要监视或模拟那些较低级别的服务,以便通过检查被调用的较低级别服务来验证被测较高级别服务的行为是否符合预期。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用Karma / Jasmine / JSPM对角度服务进行单元测试 - Unit-testing an angular service with Karma/Jasmine/JSPM Angular.js承诺在使用业力进行单元测试服务时无法解决 - Angular.js promise not resolving when unit testing service with karma 有条件地解决或拒绝$ q promise,使用Jasmine进行单元测试 - Conditionally resolve or reject $q promise, unit testing with Jasmine 如何在角组件与服务交互的地方使用茉莉花因果单元测试来测试.subscribe方法? - How to test .subscribe method using jasmine karma unit testing where angular components is interacting with service? Angular单元测试服务返回Promise Jasmine - Angular unit test a service return Promise Jasmine Angular 8 Jasmine 和业力测试:模拟的 ngonit promise 值未在 DOM 中呈现 - Angular 8 Jasmine and karma testing: mocked ngonit promise value is not rendered in the DOM 使用EJS指数进行Angma Karma-Jasmine单元测试 - Angular Karma-Jasmine Unit Testing with EJS index 使用Karma-Jasmine在Angular内以承诺测试服务 - Test a service with a promise inside in Angular with Karma-Jasmine 单元测试茉莉花角服法 - Unit testing an angular service method in jasmine 测试角度服务,异步返回Jasmine 2.0中的$ q Promise - Test Angular Service that Returns a $q Promise in Jasmine 2.0 Asynchronously
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM