在 $rootScope.$apply() 完成解析承诺之前执行的测试规范
Test spec executing before $rootScope.$apply() is done resolving promise
我正在使用 Jasmine 和 angular-mocks
' httpBackend
.
编写 angular 单元测试
我已经设法正确地模拟了我的后端,但是我的一些测试在请求完成后(在 then()
中)将值设置为 scope
的 http 调用存在一些问题。
控制器:
$scope.startShift
绑定到按钮点击。
app.controller('ShiftStartCntl', function($scope, $rootScope, $location, Restangular, $http, shifts) {
$scope.shifts = shifts;
$scope.startShift = function (category) {
$scope.startingShift = true;
baseShifts.post({category_number: 2})
.then(function (shift) {
$scope.shift = shift;
// breaks here if run as the endpoint isn't mocked
$http.post('endpointThatIsNotMocked').then(function() {});
$location.path($scope.rootURL + '/shift/' + shift.id + '/');
$scope.startingShift = false;
});
});
测试:
// module definition and stuff
//
// [...]
//
describe('ShiftStartCntl', function() {
var scope, rootScope, httpBackend, ShiftStartCntl;
beforeEach(angular.mock.inject(function($rootScope, $controller, $httpBackend) {
scope = $rootScope.$new();
rootScope = $rootScope;
httpBackend = $httpBackend;
// mimics the controller's ng-route `resolve` dependency
shifts = getJSONFixture('leave_shifts.json');
scope.baseShifts = baseApi.all('shifts');
// used in the controller
scope.categories = getJSONFixture('leave_categories.json');
httpBackend.expectPOST('/api/shifts/', {category_number: 2})
.respond(203, {"id": 4, "user": 1,
"category_number": 2,
"sign_in": "2015-02-10T21:29:06.110Z",
"sign_out": null
});
$controller('ShiftStartCntl', {$scope: scope, shifts: []});
}));
it('should start a shift', function() {
expect(shifts.length).toEqual(2);
expect(scope.startingShift).toBe(undefined);
scope.startShift(scope.categories[1]);
rootScope.$apply();
expect(scope.shift.id).toEqual(4);
httpBackend.flush();
});
});
产生的错误如下:
PhantomJS 1.9.8 (Mac OS X) Shifts ShiftStartCntl should start a shift FAILED
Expected undefined to equal 4.
at [...]/js/tests/unit/controllers/main.js:100
Error: Unexpected request: POST yoyoyo
这是 expect(scope.shift.id).toEqual(4);
所在的行
我的问题是关于意外请求的错误应该在 expect(scope.shift.id).toEqual(4);
执行之前发生。
正如在几个 Whosebug 答案和各种博客文章中所读,我尝试使用 $rootScope.apply();
但没有成功。
关于如何解决这个问题有什么想法吗?
你能试试把httpBackend.flush();
两行移到上面
scope.startShift(scope.categories[1]);
httpBackend.flush();
rootScope.$apply();
expect(scope.shift.id).toEqual(4);
我正在使用 Jasmine 和 angular-mocks
' httpBackend
.
编写 angular 单元测试
我已经设法正确地模拟了我的后端,但是我的一些测试在请求完成后(在 then()
中)将值设置为 scope
的 http 调用存在一些问题。
控制器:
$scope.startShift
绑定到按钮点击。
app.controller('ShiftStartCntl', function($scope, $rootScope, $location, Restangular, $http, shifts) {
$scope.shifts = shifts;
$scope.startShift = function (category) {
$scope.startingShift = true;
baseShifts.post({category_number: 2})
.then(function (shift) {
$scope.shift = shift;
// breaks here if run as the endpoint isn't mocked
$http.post('endpointThatIsNotMocked').then(function() {});
$location.path($scope.rootURL + '/shift/' + shift.id + '/');
$scope.startingShift = false;
});
});
测试:
// module definition and stuff
//
// [...]
//
describe('ShiftStartCntl', function() {
var scope, rootScope, httpBackend, ShiftStartCntl;
beforeEach(angular.mock.inject(function($rootScope, $controller, $httpBackend) {
scope = $rootScope.$new();
rootScope = $rootScope;
httpBackend = $httpBackend;
// mimics the controller's ng-route `resolve` dependency
shifts = getJSONFixture('leave_shifts.json');
scope.baseShifts = baseApi.all('shifts');
// used in the controller
scope.categories = getJSONFixture('leave_categories.json');
httpBackend.expectPOST('/api/shifts/', {category_number: 2})
.respond(203, {"id": 4, "user": 1,
"category_number": 2,
"sign_in": "2015-02-10T21:29:06.110Z",
"sign_out": null
});
$controller('ShiftStartCntl', {$scope: scope, shifts: []});
}));
it('should start a shift', function() {
expect(shifts.length).toEqual(2);
expect(scope.startingShift).toBe(undefined);
scope.startShift(scope.categories[1]);
rootScope.$apply();
expect(scope.shift.id).toEqual(4);
httpBackend.flush();
});
});
产生的错误如下:
PhantomJS 1.9.8 (Mac OS X) Shifts ShiftStartCntl should start a shift FAILED
Expected undefined to equal 4.
at [...]/js/tests/unit/controllers/main.js:100
Error: Unexpected request: POST yoyoyo
这是 expect(scope.shift.id).toEqual(4);
我的问题是关于意外请求的错误应该在 expect(scope.shift.id).toEqual(4);
执行之前发生。
正如在几个 Whosebug 答案和各种博客文章中所读,我尝试使用 $rootScope.apply();
但没有成功。
关于如何解决这个问题有什么想法吗?
你能试试把httpBackend.flush();
两行移到上面
scope.startShift(scope.categories[1]);
httpBackend.flush();
rootScope.$apply();
expect(scope.shift.id).toEqual(4);