我正在尝试为我的应用编写单元测试,我有以下问题
在我的控制器中,我有类似
的东西 $scope.test1 = function() {
productFactory.getName()
.then(function(products){
$scope.result = products;
})
}
productFactory
angular.module('myApp').factory('productFactory', function($http) {
var factoryObj = {};
factoryObj.getName = function() {
return http.get(url)
}
return factoryObj
})
在我的单元测试文件中
describe('test here', function () {
var testCtrl, scope, httpBackend, mockFactory;
beforeEach(module('myApp', function($provide){
$provide.value('productFactory', mockFactory);
}));
// Initialize the controller and a mock scope
beforeEach(inject(function (_$controller_, _$rootScope_, _$httpBackend_, _productFactory_) {
scope = _$rootScope_.$new();
httpBackend = _$httpBackend_;
mockFactory = _productFactory_;
testCtrl = _$controller_('testCtrl', {
$scope: scope
});
it('should get product name', function() {
scope.test1();
//I am not sure how to test the results
});
}));
当我进行业力测试时,它给了我
TypeError: 'undefined' is not an object (evaluating 'productFactory.getName()')
我不确定如何测试http结果并修复错误。任何人都可以帮我吗?非常感谢!
答案 0 :(得分:1)
首先,您不必担心使用$provide
:
beforeEach(module('myApp'));
<强> 1。没有$httpBackend
(完全模拟服务)
然后,productFactory
将传递到您的控制器,但您希望spyOn
getName()
:
// Initialize the controller and a mock scope
beforeEach(inject(function (_$controller_, _$rootScope_, _$httpBackend_, _productFactory_) {
scope = _$rootScope_.$new();
httpBackend = _$httpBackend_;
mockFactory = _productFactory_;
// add spy for the method, wrap with $q.when so it returns a promise
spyOn(mockFactory, 'getName').and.returnValue($q.when('Pizza!'));
testCtrl = _$controller_('testCtrl', {
$scope: scope,
productFactory: mockFactory // pass in here
});
然后,您必须进行$digest
周期,以便承诺将通过:
it('should get product name', function() {
scope.test1();
// hit the $digest
scope.$apply();
// expectation
expect(scope.result).toBe('Pizza!')
});
<强> 2。使用$httpBackend
// Initialize the controller and a mock scope
beforeEach(inject(function (_$controller_, _$rootScope_, _$httpBackend_) {
scope = _$rootScope_.$new();
httpBackend = _$httpBackend_;
// set up httpBackent
httpBackend.when('GET', '/products')
.respond([{ name: 'Pizza!'}, {name: 'Sandwich'}]);
testCtrl = _$controller_('testCtrl', {
$scope: scope
});
在这种情况下,我们根本不需要嘲笑工厂。然后,当我们希望http调用返回时,我们只需要flush
$httpBackend
:
it('should get product name', function() {
scope.test1();
// hit the $digest with flush
httpBackend.flush();
// expectation
expect(scope.result.length).toBe(2)
});