問題描述
情況:
我正在對(duì)我的 Angular/Ionic 應(yīng)用程序進(jìn)行單元測(cè)試.
I am unit testing my Angular / Ionic app.
我遇到了模態(tài)問題.目前我可以測(cè)試模態(tài)是否已被調(diào)用.到此為止.我無法測(cè)試模態(tài)的正確 show() 和 hide() 方法.
I am having troubles with the modal. At the moment i can test that the modal has been called. That's all so far. I cannot test the proper show() and hide() method of the modal.
我收到以下錯(cuò)誤:
TypeError: $scope.modal_login.show is not a function
Error: show() method does not exist
TypeError: $scope.modal_login.hide is not a function
Error: hide() method does not exist
我認(rèn)為這完全取決于間諜.我不知道如何正確監(jiān)視模態(tài),我認(rèn)為一旦完成,一切都會(huì)正常工作.
I think it depends entirely on the spy. I don't know how to properly spy on the modal, and i think that once that is done, everything will work fine.
代碼:
控制器:
$scope.open_login_modal = function()
{
var temp = $ionicModal.fromTemplateUrl('templates/login.html',{scope: $scope});
temp.then(function(modal) {
$scope.modal_login = modal;
$scope.modal_login.show();
$scope.for_test_only = true;
});
};
$scope.close_login_modal = function()
{
$scope.modal_login.hide();
};
注意:open_login_modal函數(shù)的代碼已經(jīng)重構(gòu),方便測(cè)試.原來的代碼是:
Note: the code of open_login_modal function has been refactored to facilitate the test. The original code was:
$scope.open_login_modal = function()
{
$ionicModal.fromTemplateUrl('templates/login.html', {
scope: $scope
}).then(function(modal) {
$scope.modal_login = modal;
$scope.modal_login.show();
});
};
測(cè)試:
describe('App tests', function()
{
beforeEach(module('my_app.controllers'));
function fakeTemplate()
{
return {
then: function(modal){
$scope.modal_login = modal;
}
}
}
beforeEach(inject(function(_$controller_, _$rootScope_)
{
$controller = _$controller_;
$rootScope = _$rootScope_;
$scope = _$rootScope_.$new();
$ionicModal =
{
fromTemplateUrl: jasmine.createSpy('$ionicModal.fromTemplateUrl').and.callFake(fakeTemplate)
};
var controller = $controller('MainCtrl', { $scope: $scope, $rootScope: $rootScope, $ionicModal: $ionicModal });
}));
describe('Modal tests', function()
{
beforeEach(function()
{
$scope.open_login_modal();
spyOn($scope.modal_login, 'show'); // NOT WORKING
spyOn($scope.modal_login, 'hide'); // NOT WORKING
});
it('should open login modal', function()
{
expect($ionicModal.fromTemplateUrl).toHaveBeenCalled(); // OK
expect($ionicModal.fromTemplateUrl.calls.count()).toBe(1); // OK
expect($scope.modal_login.show()).toHaveBeenCalled(); // NOT PASS
expect($scope.for_test_only).toEqual(true); // NOT PASS
});
it('should close login modal', function()
{
$scope.close_login_modal();
expect($scope.modal_login.hide()).toHaveBeenCalled(); // NOT PASS
});
});
});
從代碼 $scope.for_test_only 可以看出,它應(yīng)該等于 true,但無法識(shí)別.我收到此錯(cuò)誤消息:
As you can see from the code $scope.for_test_only it should be equal to true but is not recognized. I get this error message instead:
Expected undefined to equal true.
show() 和 hide() 方法也是如此.測(cè)試中看不到它們.
The same happens to the show() and hide() method. They are not seen by the test.
我認(rèn)為是因?yàn)樗鼈儧]有在間諜中聲明.
And i think because they are not declared in the spy.
問題:
我怎樣才能正確地監(jiān)視模式?
How can i properly spy on a modal?
非常感謝!
推薦答案
這里的問題可以推斷為如何正確地窺探 Promise.您在這里非常正確.
The question here could be extrapolated to how to properly spy on a promise. You are very much on the right track here.
但是,如果你想測(cè)試調(diào)用成功的回調(diào)函數(shù),你必須執(zhí)行兩個(gè)步驟:
However, if you want to test that whatever your callback to the success of the promise is called, you have to execute two steps:
- 模擬服務(wù)(在您的情況下為 $ionicModal)并返回一些假函數(shù)
- 在該假函數(shù)中,執(zhí)行生產(chǎn)代碼傳遞給您的回調(diào).
這是一個(gè)插圖:
//create a mock of the service (step 1)
var $ionicModal = jasmine.createSpyObj('$ionicModal', ['fromTemplateUrl']);
//create an example response which just calls your callback (step2)
var successCallback = {
then: function(callback){
callback.apply(arguments);
}
};
$ionicModal.fromTemplateUrl.and.returnValue(successCallback);
當(dāng)然,如果您不想自己維護(hù)承諾,您可以隨時(shí)使用 $q:
Of course, you can always use $q if you don't want to be maintaining the promise on your own:
//in your beforeeach
var $ionicModal = jasmine.createSpyObj('$ionicModal', ['fromTemplateUrl']);
//create a mock of the modal you gonna pass and resolve at your fake resolve
var modalMock = jasmine.createSpyObj('modal', ['show', 'hide']);
$ionicModal.fromTemplateUrl.and.callFake(function(){
return $q.when(modalMock);
});
//in your test
//call scope $digest to trigger the angular digest/apply lifecycle
$scope.$digest();
//expect stuff to happen
expect(modalMock.show).toHaveBeenCalled();
這篇關(guān)于Karma-Jasmine:如何正確監(jiān)視 Modal?的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!