我正在构建一个基于Breeze和Angular的应用程序
他们一起工作很好,但单元测试是一个问题。
这是一个非常香草的测试但是Breeze一直在中间:
describe('myController', function () {
beforeEach(inject(function ($injector) {
module('app');
$httpBackend = $injector.get('$httpBackend');
authRequestHandler = $httpBackend.whenGET().respond(200,
{"someStrings": ["foo", "bar"]})
//more uninteresting code...
createController = function () {
return $controller('myController', { '$scope': $rootScope });
};
}));
it('should fetch authentication token', function () {
$httpBackend.expectGET('/auth.py');
var controller = createController();
$httpBackend.flush();
});
问题在于Breeze一直在被初始化。执行时,我收到以下消息:
Error: cannot execute _executeQueryCore until metadataStore is populated.
//or,with different get: ... $httpBackend.when('GET', '/auth.py')
// .respond({ userId: 'userX' });
Error: Unexpected request: GET breeze/Breeze/Metadata No more request expected
如何阻止或模拟或存根Breeze,这样就不会干扰我的测试...例如,这些测试的目的是验证,而不是数据。
答案 0 :(得分:0)
微风本身不是“中间”。 Breeze不会参与您的$http
授权电话。如果你能告诉我它,我会吃掉我的帽子。你没有表明它在这里。
但是你已经提出了一个关于应用程序引导程序设计的非常有趣的观点以及该设计对测试的影响。
显然,您的app
模块的启动方法或控制器的创建逻辑执行Breeze查询(可能两者都执行)。我从两个事实中推断出这一点:
异常来自executeQueryCore
,只有在您明确执行Breeze查询时才会发生
您不会在测试中触摸控制器,beforeEach
或it
中都没有触及控制器,这意味着这些呼叫(以及您的授权呼叫)也是由某种类型的在it
规范之前执行的自动启动逻辑。
在你的测试中,你已经麻烦地模拟了auth调用(在你的启动逻辑中),而不是Breeze调用。
我不知道你究竟想测试什么。为什么要测试控制器是否获取了身份验证令牌?这真的是控制器的关注吗?
也许您提出此测试仅仅是为了说明您在测试控制器时遇到的问题而不涉及真正的服务器?
让我退后一步,提出一个更重要,更一般的观点。我们必须警惕自动启动逻辑,无论它隐藏在app模块start
还是隐藏在控制器的构造函数中。特别要注意涉及调用服务器的启动逻辑。
我倾向于在我的测试的大部分中禁用自动启动逻辑。在调用ngMock的inject
函数之前,我经常在测试模块设置期间将测试双精度替换为麻烦的依赖服务。我确保app.start
方法的回调仅使用容易伪造的依赖服务。
我想通过使用$httpBackend
模拟HTTP响应来使用实际的依赖关系进行开发,然后您必须为为其收到的每个请求准备$httpBackend
启动代码...包括请求您使用Breeze 。
我最后重申 Breeze只做你告诉它做的事。它完全没有意识到您的直接转移到$http
。