简体   繁体   English

在AngularJS中承诺控制器后如何进行单元测试?

[英]How to unit test after promise of a controller in AngularJS?

I have a controller that has a callback inside: 我有一个内部有回调的控制器:

angular.module('controllers').controller('headerController', headerController);

function headerController(headerService) {
    var self = this;

    headerService.getHeaderContentData()
        .then(function(response) {
            self.contentData = response.content;
        });
}

My problem is that I need to check the value of contentData in an unit test. 我的问题是我需要在单元测试中检查contentData的值。 The idea is when I call expect(ctrl.contentData).to.be.defined passes the test, but the value of ctrl.contentData is undefined . 这个想法是当我调用expect(ctrl.contentData).to.be.defined通过测试时,但是ctrl.contentData的值是undefined Is there a way to test this behavior (test the self.contentData when the callback occurs)? 有没有一种方法可以测试这种行为(发生回调时测试self.contentData)?

Current unit test: 当前单元测试:

describe("controller", function() {
    var controller, $httpBackend;

    beforeEach(angular.mock.inject(function($injector, _$httpBackend_){
        var $controller = $injector.get('$controller');
        $httpBackend = _$httpBackend_;

        var $scope = {};
        $httpBackend.when('GET', '/data/header.content.json')
                    .respond(require('../../mock-data/header.content.json'));
        var controller = $controller('headerController', { $scope: $scope });
        $httpBackend.flush();
    }));

    it("should have contentData property populated", function() {
        expect(controller.contentData).to.exist; // <- here fails: current value is undefined
    });
});

My unit testing framework is jasmine 我的单元测试框架是茉莉花

Since your controller doesn't use $hhtp , there is no reason to handle it in the test. 由于您的控制器不使用$hhtp ,因此没有理由在测试中处理它。 The proper way to test your headerController is to mock your headerService . 测试headerController的正确方法是模拟headerService

Mock a service: 模拟服务:

beforeEach(module(function($provide) {
    mockService = jasmine.createSpyObj('headerService', ['getHeaderContentData']);
    $provide.value('headerService', mockService);
}));

beforeEach(inject(function($controller) {
    ctrl = $controller('headerController');
}));

Now, you need to mock getHeaderContentData() to return a promise - use $q. 现在,您需要模拟getHeaderContentData()以返回承诺-使用$ q。

Mock service method: 模拟服务方式:

it('should change after promise resolved', inject(function($q, $rootScope) {
    //create promise
    deferred = $q.defer();

    //mock service response (foc controller's constructor)
    mockService.getHeaderContentData.and.returnValue(deferred.promise);

    //call init()
    ctrl.init();

    expect(ctrl.contentData).toBeNull();

    deferred.resolve('Hello World');

    //not yet...
    expect(ctrl.contentData).toBeNull();

    //from angular $q dosumentation:
    //"it's important to know that the resolution of promises is tied to the digest cycle"
    $rootScope.$apply();

    //now!
    expect(ctrl.contentData).toBe('Hello World');

}));

see jsFiddle jsFiddle

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM