问题
This post follow this I've posted an other thread with a easier example
code to test
'use strict';
var app = angular.module('myApp', []);
app.run(function ($rootScope, Menus) {
var menus = [
{
'permission': null,
'title': 'Home',
'link': 'home'
},
{
'permission': 'users',
'title': 'User',
'link': 'user_actions.list'
}
];
$rootScope.menus = [];
function queryMenu(menus) {
Menus.query(menus).then(
function (result) {
$rootScope.menus = result.data;
},
function (reason) {
throw new Error(reason);
}
);
}
$rootScope.valueSetInRun = 555;
queryMenu(menus);
});
app.factory('Menus', function($http) {
return {
query : function(menus){
return $http.get('menus.json');
}
};
});
app.factory('UserFactory', function($http){
return $http.get('users.json')
});
app.controller('MainCtrl', function($scope, UserFactory) {
$scope.users = [];
$scope.text = 'Hello World!';
UserFactory.then(function(data){
$scope.users = data.data;
});
});
test
'use strict';
describe('Run', function() {
beforeEach(module('myApp'));
var $httpBackend;
beforeEach(inject(function($rootScope,_$httpBackend_) {
$httpBackend = _$httpBackend_;
console.log('beforeEach');
}));
afterEach(function() {
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});
it('should allow me to test the run() block', inject(function ($rootScope,$httpBackend) {
console.log('it block');
// Doesn't work take a look at https://stackoverflow.com/questions/25363969/karma-angularjs-how-to-test-run-block-with-an-asynchronous-service
$httpBackend.when('GET', 'menus.json').respond([{id: 1, name: 'Bob'}, {id:2, name: 'Jane'}]);
$httpBackend.flush();
expect( $rootScope.valueSetInRun ).toBe(555);
console.log($rootScope.menus);
}));
});
describe('MainCtrl', function(){
var scope, $httpBackend;//we'll use these in our tests
//mock Application to allow us to inject our own dependencies
beforeEach(module('myApp'));
//mock the controller for the same reason and include $rootScope and $controller
beforeEach(inject(function( $controller,_$rootScope_, _$httpBackend_){
$httpBackend = _$httpBackend_;
$httpBackend.when('GET', 'users.json').respond([{id: 1, name: 'Bob'}, {id:2, name: 'Jane'}]);
//create an empty scope
scope = _$rootScope_.$new();
//declare the controller and inject our empty scope
$controller('MainCtrl', {$scope: scope});
$httpBackend.flush();
}));
afterEach(function() {
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});
it('should have variable text = "Hello World!"', function(){
expect(scope.text).toBe('Hello World!');
});
it('should fetch list of users', function(){
//expect(scope.users.length).toBe(2);
//expect(scope.users[0].name).toBe('Bob');
});
});
that give me this error
**Error: Unexpected request: GET menus.json
No more request expected**
END UP see the reply of @scarIz
beforeEach(module('myApp'));
var $httpBackend;
beforeEach(inject(function( _$httpBackend_) {
$httpBackend = _$httpBackend_;
$httpBackend.when('GET', 'menus.json').respond([{
id: 1,
name: 'Bob'
}])
$httpBackend.flush();
}));
afterEach(function() {
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});
describe('Init', function() {
describe('MainCtrl', function(){
var scope, $httpBackend,$rootScope;//we'll use these in our tests
//mock Application to allow us to inject our own dependencies
//mock the controller for the same reason and include $rootScope and $controller
beforeEach(inject(function( $controller,_$rootScope_, _$httpBackend_){
$httpBackend = _$httpBackend_;
$httpBackend.when('GET', 'users.json').respond([{
id: 1,
name: 'Bob'
}, {
id:2,
name: 'Jane'
}]);
$rootScope = _$rootScope_;
//create an empty scope
scope = _$rootScope_.$new();
//declare the controller and inject our empty scope
$controller('MainCtrl', {
$scope: scope
});
$httpBackend.flush();
}));
afterEach(function() {
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});
it('should have variable text = "Hello World!"', function(){
expect(scope.text).toBe('Hello World!');
});
it('should fetch list of users', function(){
expect(scope.users.length).toBe(2);
expect(scope.users[0].name).toBe('Bob');
expect( $rootScope.valueSetInRun ).toBe(555);
console.log($rootScope.menus);
});
});
});
回答1:
The reason for your error is that Menus.query
will run before every test you perform for the myApp
module as it's called in the module's .run()
configuration. While you have provided a backend definition in your Run
test suite, you have not done so for MainCtrl
.
Therefore, to counter this, you might want to use a global beforeEach
block that runs before every test, which should be defined in a helper file to be included prior to your specs:
beforeEach(inject(function($httpBackend) {
$httpBackend.when('GET', 'menus.json').respond([{id: 1, name: 'Bob'}])
$httpBackend.flush();
}));
来源:https://stackoverflow.com/questions/25387375/karma-angularjs-how-to-test-run-block-with-service