gpt4 book ai didi

unit-testing - 如何模拟 angularjs 应用程序的后端?

转载 作者:行者123 更新时间:2023-12-04 05:04:03 26 4
gpt4 key购买 nike

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

失败。

最佳答案

这是您发布的工厂的工作测试。我为注入(inject)的 httpBackend 添加了一个变量 $httpBackend。并调用 $httpBackend.flush()。 fiddle-demo (阅读到最后以获得 fiddle 内容的完整描述)

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();。因为services in angularjs are singletons ,在您的应用程序中,您将只拥有实例化时的数据。因此,以后对数据的修改将不会反射(reflect)在您的工厂中。这是一个反射(reflect)这个想法的工厂及其单元测试的例子。

工厂:

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”。希望这会有所帮助。

关于unit-testing - 如何模拟 angularjs 应用程序的后端?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20412192/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com