我有以下角度服务。
(function () {
"use strict";
angular.module("theModule")
.factory("theService", theServiceFactory);
function theServiceFactory() {
return {
theFn: theFn,
theFailureFn: theFailureFn,
theSuccessFn: theSuccessFn
};
function theFn() {
angular.noop();
}
function theFailureFn() {
theFn();
}
function theSuccessFn() {
this.theFn();
}
}
}());
函数是单独定义的,它们的引用分配给工厂返回的对象。
我有以下茉莉花测试案例。
describe("The Service Test Specifications", function () {
var theService;
beforeEach(module('theModule'));
beforeEach(inject(function(_theService_) {
theService = _theService_;
}));
it("should call 'theFn' from 'theFailureFn'", function () {
spyOn(theService, "theFn");
theService.theFailureFn();
expect(theService.theFn).toHaveBeenCalled();
});
it("should call 'theFn' from 'theSuccessFn'", function () {
spyOn(theService, "theFn");
theService.theSuccessFn();
expect(theService.theFn).toHaveBeenCalled();
});
});
测试用例should call 'theFn' from 'theFailure'
正在失败,而should call 'theFn' from 'theSuccess'
正在传递。
从源代码来看,似乎object's theFn
指的是function theFn
但实际上并非如此。它导致第一个测试用例失败。 (Q1)在什么阶段将不同的引用分配给object's theFn
?
在theFn
内this
调用theSuccess
时,第二个测试用例正在传递。但在这种情况下使用this
是严格模式违规。我喜欢并关注John Papa's style guide所以我创建了factory
并定义了它下面的所有函数。 (Q2)编写此类函数的更好方法是什么?
(Q3)如果theFailure
写得正确,有没有办法在测试用例中检测到function theFn
被调用?
答案 0 :(得分:3)
它实际上是从theFn()
调用theFailureFn()
,而不是从theFn()
调用sucesssFn()
。这是你测试的相反结果。
如你所见,
http://plnkr.co/edit/Tp5FtsL8DAjkcPO0m0ZV?p=preview
console.log('theService.theFn BEFORE spyOn', theService.theFn);
spyOn(theService, "theFn");
console.log('theService.theFn AFTER spyOn', theService.theFn);
结果
theService.theFn BEFORE spyOn theFn()
theService.theFn AFTER spyOn j$.createSpy.spy()
您的Jasmine spyOn(theService, "theFn");
正在设置服务实例this.theFn
,您的测试是否正在调用this.theFn
。请记住,theService
是哈希,而不是函数。
从这一行的输出中可以看出;
console.log('caller theFailureFn', this, theFn, this.theFn)
//OUTPUT
caller theFailureFn Object {} theFn() j$.createSpy.spy()
theFn
和this.theFn
非常不同。 theFn
是对象属性值,this.theFn
是对象Hash的实例。
要回答你的问题,
(Q1)在什么阶段将不同的参考分配给对象theFn
{1}}按预期分配。 theFn
makkes在您的情况下存在差异。
(Q2)编写此类函数的更好方法是什么?
要测试一个函数调用一个对象的函数,它应该返回一个函数,而不是一个哈希。
(Q3)如果故障写得正确,有没有办法在测试用例中检测到函数fn被调用? 与Q2相同的答案。
答案 1 :(得分:1)
请勿在{{1}}中使用this
。 Factory只是作为函数执行,它只返回您明确指定为返回对象的内容。 Angular使用.factory()
作为构造函数,使用.service()
运算符执行,这就是您将使用new
的位置。
这意味着您的this
写得正确。
至于Q3,它可能会因为spyOn的实现方式而失败。
编辑:
正如我想的那样,它是theFailureFn()
的实现。
spyOn包装了该功能,但在您的工厂中,您仍然在引用原始功能。尝试使用spyOn()