Angularjs 测试角度请求
在了解如何在工厂上测试$http请求时遇到问题 基本工厂:Angularjs 测试角度请求,angularjs,mocha.js,sinon,chai,angular-mock,Angularjs,Mocha.js,Sinon,Chai,Angular Mock,在了解如何在工厂上测试$http请求时遇到问题 基本工厂: angular.module('myServices', []) .factory('myFactory', function($http) { return { postLog: function(logData) { logData.newProperty = 'my new property'; return $http
angular.module('myServices', [])
.factory('myFactory', function($http) {
return {
postLog: function(logData) {
logData.newProperty = 'my new property';
return $http.post('/log', logData);
};
};
});
现在我想测试一下,以确保我已经添加了我的newProperty
。我希望能够编写如下测试:
it('adds a new property before POSTing', function() {
MyFactory.postLog({message: 'posting a log!'});
// catch the request somehow
expect(theRequest.data).to.have.property('newProperty');
});
我最初的想法是,$httpBackend.expect
会让我访问请求,但它似乎只有一个.respond
方法,没有其他方法:
var MyFactory, backend;
beforeEach(function() {
module('exampleApp');
inject(function($httpBackend, _myFactory_) {
backend = $httpBackend;
backend.expect('POST', '/log').??? // would be nice to have a `.request` method here or a parameter passed to `.respond`
MyFactory = _myFactory_;
});
});
因此,我尝试通过以下操作设置一个httpInterceptor
:
var MyFactory, theRequest;
beforeEach(function() {
module('exampleApp', function($provide, $httpProvider) {
$provide.service('requestCatcher', function() {
this.request = function(req) {
console.log(req);
request = req;
return req;
};
});
$httpProvider.interceptors.push('requestCatcher');
});
inject(function(_myFactory_) {
MyFactory = _myFactory_;
});
});
it('adds a new property before POSTing', function() {
MyFactory.postLog({message: 'posting a log!'});
expect(theRequest.data).to.have.property('newProperty');
});
但拦截器从未真正开火(日志不会打印到日志中)。我对这个有点没主意了
也许我在
postLog
方法中添加了新的属性,这违反了一些原则,应该重构成自己的方法以实现可测试性?尽管如此,如果有一种方法可以进入出站请求,那将是非常好的,即使它将被$httpBackend“捕获”。期待Angularjs gitter.im上的优秀人员提供:
$httpBackend.expect('POST', '/log').respond(function(method, url, data, headers) {
var mockReturnData = [{...}, {...}];
console.log(data); // this is the data that was sent to the endpoint
return [200, mockReturnData];
});
在任何地方都找不到这个您已经走上了正确的道路,但是您应该在beforeach()函数中创建mock,以实现多功能性
describe('MyFactory', function() {
var $httpBackend, userMock, MyFactory;
beforeEach(inject(function(_$httpBackend_, _MyFactory_) {
$httpBackend = _$httpBackend_;
MyFactory = _MyFactory_;
userMock = {user: {id: 1, name: 'shy guy'}};
}));
it('should pass', function() {
$httpBackend.expectGET('/api/path/to/your/endpoint').respond(userMock);
MyFactory.postLog({message: 'whatever'});
$httpBackend.flush(); // Will dump the test data from the endpoint we specified above.
expect(true).toBe(true);
});
});
这是怎么回事?
expectGET
准备在测试中调用指定url时的响应数据
flush()
请注意,如果您调用expectGET
,但实际上没有向指定的url发出请求,测试将失败
继续测试!超值:)