我想测试一个运行$ resource的工厂方法.我的测试会嘲笑那个尚不存在的真实后端.
这是一个示例工厂代码:
app.factory( 'Global', function( $resource ){ var Jogas = $resource('/jogasok/:id', {'id': '@id'}, { 'ujBerlet': {'method': 'POST', 'params': {'berlet': true}} }); var jogasok = Jogas.query(); return { getJogasok: function() { return jogasok; } }; })
我的测试是检查查询是否已经完成.
如果我用以下内容初始化我的应用:
app.run( function run ($httpBackend) { $httpBackend.whenGET('/jogasok').respond([ {id: 1, name: 'asdfasdf'}, {id: 2, name: '2wrerwert'} ]); })
并在我的浏览器中打开应用程序,然后一切似乎都很好,我在浏览器中有虚拟数据.
但是,当我拿出上面的运行代码并编写测试时,事情就不起作用了.
describe( 'Global Service: ', function() { beforeEach( module('bkJoga') ); beforeEach( inject(function($httpBackend) { $httpBackend.whenGET('/jogasok').respond([ {id: 1, name: 'asdfasdf'}, {id: 2, name: '2wrerwert'} ]); })); it('getJogasok should return everyone', inject(function(Global) { expect(JSON.stringify(Global.getJogasok())).toBe(JSON.stringify([ {id: 1, name: 'asdfasdf'}, {id: 2, name: '2wrerwert'} ])); })); });
失败.
这是您发布工厂时的工作测试.我为注入的httpBackend添加了一个变量$ httpBackend.并调用$ httpBackend.flush().fiddle-demo(阅读结尾以获取小提琴内容的完整描述)
describe( 'Global Service: ', function() { var Global, $httpBackend // load the relevant application module, with the service to be tested beforeEach( module('bkJoga') ); beforeEach( function() { // inject the mock for the http backend inject(function(_$httpBackend_) { $httpBackend = _$httpBackend_; }); // mock the response to a particular get request $httpBackend.whenGET('/jogasok').respond([ {id: 1, name: 'asdfasdf'}, {id: 2, name: '2wrerwert'} ]); // inject the service to be tested inject(function(_Global_) { Global = _Global_; }); }); it('should exist', function() { expect(!!Global).toBe(true); }); it('getJogasok should return everyone', function() { $httpBackend.flush(); // <------------ need to flush $httpBackend expect(JSON.stringify(Global.getJogasok())).toBe(JSON.stringify([ {id: 1, name: 'asdfasdf'}, {id: 2, name: '2wrerwert'} ])); }); });
无论如何,我会以不同的方式重写工厂,因为,正如当前编写的那样,它仅在实例化时才查询数据库var jogasok = Jogas.query();
.因为angularjs中的服务是单例,所以在您的应用程序中,您将只拥有实例化时的数据.因此,以后对数据的修改不会反映在您的工厂中.以下是反映这一想法的工厂及其单元测试的示例.
工厂:
app.factory('GlobalBest', function ($resource) { return $resource('/jogasok/:id', { 'id': '@id' }, { 'ujBerlet': { 'method': 'POST', 'params': { 'berlet': true } } }); });
考试:
describe('GlobalBest Service: ', function () { var srv, $httpBackend; beforeEach(module('bkJoga')); beforeEach(function () { // inject the mock for the http backend inject(function (_$httpBackend_) { $httpBackend = _$httpBackend_; }); // inject the service to be tested inject(function (_GlobalBest_) { srv = _GlobalBest_; }); }); it('should exist', function () { expect( !! srv).toBe(true); }); it('query() should return everyone', function () { // mock the response to a particular get request $httpBackend.whenGET('/jogasok').respond([{ id: 1, name: 'asdfasdf' }, { id: 2, name: '2wrerwert' }]); // send request to get everyone var data = srv.query(); // flush the pending request $httpBackend.flush(); expect(JSON.stringify(data)).toBe(JSON.stringify([{ id: 1, name: 'asdfasdf' }, { id: 2, name: '2wrerwert' }])); }); it('get({id: 1}) should return object with id=1', function () { // mock the response to a particular get request $httpBackend.whenGET('/jogasok/1').respond({ id: 1, name: 'asdfasdf' }); var datum = srv.get({ id: 1 }); $httpBackend.flush(); expect(JSON.stringify(datum)).toBe(JSON.stringify({ id: 1, name: 'asdfasdf' })); }); });
我写了一个fiddle-demo有3个版本的服务:你的原始服务'Global',一个返回query()方法的新版本'GlobalNew',最后是一个直接返回$ resource的版本'GlobalBest'.希望这可以帮助.