如何嘲笑为angularjs应用后端?后端、angularjs

2023-09-13 03:26:03 作者:无人街七号

我想测试运行$资源的工厂方法。我的测试将模拟尚不存在真正的后台。

I would like to test a factory method that runs $resource. My test would mock the real backend that does not exist yet.

下面是一个简单的工厂code:

Here is a sample factory code:

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;
    }
  };
})

我的测试是检查该查询被做了。

My test would be to check that query was made.

如果我初始化我的应用程序:

If I initialize my app with:

app.run( function run ($httpBackend) {
  $httpBackend.whenGET('/jogasok').respond([
        {id: 1, name: 'asdfasdf'}, 
        {id: 2, name: '2wrerwert'}
      ]);
})

在我的浏览器中打开应用程序,然后一切似乎都很正常,我在浏览器中的虚拟数据。

and open the app in my browser, then everything seems to be fine, I have the dummy data in the browser.

但是,当我拿出来看code以上,并且编写一个测试,事情根本无法工作。

But, when I take out the run code above, and write a test, things just don't work.

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()的调用。 小提琴-演示 (读到结尾对于小提琴内容的描述)

Here is a working test for the factory as you posted it. I added a variable $httpBackend for the injected httpBackend. And a call to $httpBackend.flush(). fiddle-demo (read to the end for full description of fiddle content)

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服务单身的,在你的应用程序,你将只有数据它们在实例中的时间。因此,修改后的数据不会反映在你的工厂。这里是工厂及其单元测试反映这种思想的一个例子。

In any event, I would rewrite the factory a bit differently, because, as it is currently written, it queries the database only upon instantiation var jogasok = Jogas.query();. Because services in angularjs are singletons, in your app you will have only the data as they are at the time of instantiation. Therefore, later modifications to the data will not be reflected in your factory. Here is an example of the factory and its unit-test that reflects this idea.

工厂:

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'
        }));
    });
});

我写了 小提琴-演示 3个版本的服务:你原来服务'全球',一个新版本GlobalNew返回查询()方法,最后直接返回$资源的一个版本GlobalBest。希望这有助于。

I wrote a fiddle-demo with 3 versions of the service: your original service 'Global', a new version 'GlobalNew' that returns the query() method, and finally a version 'GlobalBest' that returns directly the $resource. Hope this helps.

 
精彩推荐