AngularJS - 修改后的对象不会从一个测试进入下一个测试

时间:2015-12-07 05:39:27

标签: javascript angularjs unit-testing jasmine

所以我在AngularJS应用程序的service中有这个简单的对象:

    this.testObj = [
        {'id': 0, 'label': 'Hello'}
    ];

.service('MainSvc', function () {

调用内部

在控制器中,我有:

.controller('MainCtrl', function MainCtrl($scope, MainSvc) {
    this.testObj = MainSvc.testObj;
});

问题是,我正在进行Karma / Jasmine测试,并且直到第二次测试才进行...它无法识别对象已经改变并获得新的。

这是一个模拟的单元测试。

describe('Mocked Unit Test', function() {
    'use strict';

    beforeEach(module('ui.router'));
    beforeEach(module('main'));

    var MainSvc, scope, http, mockMain;

    beforeEach(angular.mock.inject(function($rootScope, MainSvc, $controller, $injector){
        scope = $rootScope.$new();
        mockMain = $injector.get('MainSvc');

        $controller('MainCtrl', {
            $scope: scope,
            MainSvc: mockMain
        });

        scope.$digest();
    }));

    it('should expect item to be defined', inject(function() {
        expect(mockMain.testObj).toBeDefined(); // passes
        mockMain.testObj[1] = {id: 2, label: "World"};
        console.log(mockMain.testObj); // [Object{id: 0, label: 'Hello'}, Object{id: 2, label: 'World'}]
        console.log('Length: ' + Object.keys(mockMain.testObj).length); // Length: 2
    }));

    it('expect the testObj object to have a 2nd index', inject(function() {
        console.log(mockMain.testObj); // [Object{id: 0, label: 'Hello'}]
        console.log('Length: ' + Object.keys(mockMain.testObj).length); // Length: 1

        // Where is testObj[1] from when it was added in the first test?
    }));
});

从内嵌注释中可以看出,第二个it()测试中的对象没有看到mockMain.testObj的对象发生了变化。

或者我可能错了吗?

请帮忙。谢谢。

1 个答案:

答案 0 :(得分:0)

测试不依赖于彼此,它们是孤立的。这是主要的单元测试原则之一。如果您想在两个测试之间找到共同点,则应使用beforeEach()

beforeEach(angular.mock.inject(function($rootScope, MainSvc, $controller, $injector){
    scope = $rootScope.$new();
    mockMain = $injector.get('MainSvc');

    $controller('MainCtrl', {
        $scope: scope,
        MainSvc: mockMain
    });

    mockMain.testObj[1] = {id: 2, label: "World"};
    scope.$digest();
}));

it('should expect item to be defined', inject(function() {
    expect(mockMain.testObj).toBeDefined(); // passes
    console.log(mockMain.testObj); 
    console.log('Length: ' + Object.keys(mockMain.testObj).length); // Length: 2
}));

it('expect the testObj object to have a 2nd index', inject(function() {
    console.log(mockMain.testObj); 
    console.log('Length: ' + Object.keys(mockMain.testObj).length); 
}));

或者您可以添加其他describe块并在其中使用beforeEach()

beforeEach(angular.mock.inject(function($rootScope, MainSvc, $controller, $injector){
    scope = $rootScope.$new();
    mockMain = $injector.get('MainSvc');

    $controller('MainCtrl', {
        $scope: scope,
        MainSvc: mockMain
    });

    scope.$digest();
}));

it('should expect item to be defined', inject(function() {
    expect(mockMain.testObj).toBeDefined(); // passes
    mockMain.testObj[1] = {id: 2, label: "World"};
    console.log(mockMain.testObj); // [Object{id: 0, label: 'Hello'}, Object{id: 2, label: 'World'}]
    console.log('Length: ' + Object.keys(mockMain.testObj).length); // Length: 2
}));

describe('having two elements in the array', function() {
    beforeEach(function() {
        mockMain.testObj[1] = {id: 2, label: "World"};
    });

    it('expect the testObj object to have a 2nd index', inject(function() {
        console.log(mockMain.testObj); 
        console.log('Length: ' + Object.keys(mockMain.testObj).length); 
    }));

});

此外,对您在测试中定义的内容进行断言似乎是错误的。通过在数组中设置第二个元素,然后测试其长度,您只需验证本机javascript分配。