工厂方法引用混淆,并指导其编码
Factory method reference confusion, and guideline to code it
我有以下angular服务:
(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
与theSuccess
内部的this
调用。但是在这种情况下使用this
是严格违反模式的。我喜欢并遵循John Papa的风格指南,所以我创建了factory
并定义了它下面的所有函数。(Q2)如何更好地编写这样的函数?
(Q3)如果theFailure
写得正确,是否有任何方法可以在测试用例中检测function theFn
被调用?
Plunkr: http://plnkr.co/edit/PsQTZQlIgWI3OTMaYi7n
它实际上是从theFailureFn()
调用theFn()
,而不是从sucesssFn()
调用theFn()
。这和你的测试结果相反。
如你所见,
http://plnkr.co/edit/Tp5FtsL8DAjkcPO0m0ZV?p =
预览 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)在什么阶段不同的引用被分配给对象的theFntheFn
按您的期望分配。spyOn
对你的情况很重要。
(Q2)如何更好地编写这样的函数?
要测试一个函数调用一个对象的函数,它应该返回一个函数,而不是一个散列。
(Q3)如果failure写得正确,是否有任何方法可以在测试用例中检测函数theFn被调用?和Q2一样。
不要在.factory()
中使用this
。Factory只是作为函数执行它只是返回你显式指定的返回对象。Angular使用.service()
作为构造函数,它使用new
运算符执行,在这里你将使用this
。
这意味着你的theFailureFn()
是正确的。
对于Q3,它可能会因为spyOn的实现方式而失败。
编辑:如我所料,这是spyOn()
的实现。
spyOn包装了函数,但是在你的工厂中你仍然引用原始函数。尝试使用expect(this.theFn).toHaveBeenCalled();
- HackReactor,编码窗口现在可以访问一个名为“”的对象;招生;使用名为“;showApp”;.调用此方法时不带任
- 使用 MVC 删除 JavaScript 中硬编码字符串 Asp.Net 最佳方法
- 在我的代码中管理大量硬编码数据的最佳方法
- 使用 POST 方法通过 ajax 发送的数据在发送到服务器之前是否必须进行 URL 编码
- 我在jQuery中有一个循序渐进的过程,有没有更好的编码方法
- 有没有什么干净的方法可以对一组||测试进行编码,看看变量的值是否在其中一个测试中
- 对区间[1,10^12]中的整数进行编码/解码的快速有效方法是什么
- 在敲除js中,这两种编码方法有什么区别
- 在 url 中编码特殊字符的最佳方法
- 取消之前对谷歌地图地理编码方法的调用
- 对 url 的西里尔字母进行编码的最快方法
- 使用angularJS将json模板编码为html的方法是什么
- 对 URI 组件非 utf-8 字符进行编码并相应地解码它们的正确方法是什么
- 处理差异,在编码 URI 部分时使用 c# 和 JavaScript 方法
- 有没有更好的方法可以用JavaScript和/或jQuery进行编码
- 有没有一种方法可以在调用诺基亚反向地理编码api时将响应和查询关联起来
- 有没有跨平台的方法可以将一个字符串编码为另一个没有空格的字符串,然后将其解码回来
- 在dataURI中对元音变音符进行编码的正确方法是什么
- 关于JavaScript,有没有一种更简单的编码方法
- 在我目前的编码方法中有什么捷径吗?