如何模拟angularjs app的后端?

 望舒灬寒 发布于 2023-02-12 15:53

我想测试一个运行$ 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'}
    ]));
  }));
});

失败.

1 个回答
  • 这是您发布工厂时的工作测试.我为注入的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'.希望这可以帮助.

    2023-02-12 15:56 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有