(我将其设为社区 wiki 答案,因为坦率地说,我认为它只回答了部分问题,而留下了太多未说的内容。希望其他有更多知识的人可以改进它。) p>
但是SomeClass 仍然依赖于工厂。我该如何正确解决这个问题?
根据你链接的this article链接,你这样做:
anotherclass.js:
function AnotherClass() {
}
AnotherClass.prototype.foo = function() { /* ... */ };
AnotherClass.prototype.bar = function() { /* ... */ };
AnotherClass.prototype.baz = function() { /* ... */ };
someclass.js:
function SomeClass(a) {
// ...app logic...
// Use AnotherClass instance `a`; let's say you're going to call `foo`,
// but have no use for `bar` or `baz`
a.foo();
// ...app logic...
}
someclass-test.js:
function someClass_testSomething() {
var sc = new SomeClass({
foo: function() { /* ...appropriate `foo` code for this test... */}
});
// ...test `sc`...
}
function someClass_testSomethingElse() {
// ...
}
app.js:
function buildApp() {
return {
// ...lots of various things, including:
sc: new SomeClass(new AnotherClass())
};
}
所以真正的应用程序是使用buildApp 构建的,它为SomeClass 提供了AnotherClass 实例。您对SomeClass 的测试将使用someClass_testSomething 等,它使用真实的SomeClass,但使用模拟实例而不是真实的AnotherClass,其中包含足够测试。
不过,我的依赖注入功能很弱,坦率地说,我看不到 buildApp 如何扩展到现实世界,我也看不出如果 方法 em> 必须创建一个对象来完成它的工作,例如:
SomeClass.prototype.doSomething = function() {
// Here, I need an instance of AnotherClass; maybe I even need to
// create a variable number of them, depending on logic internal
// to the method.
};
您不会将方法所需的所有内容都作为参数传递,这将是一场意大利面条式的噩梦。这可能就是为什么对于更多的静态语言,通常会涉及工具而不仅仅是编码模式。
当然,在 JavaScript 中,我们还有另一个选择:直接在代码中使用 new AnotherClass:
anotherclass.js:
function AnotherClass() {
}
AnotherClass.prototype.foo = function() { /* ... */ };
AnotherClass.prototype.bar = function() { /* ... */ };
AnotherClass.prototype.baz = function() { /* ... */ };
someclass.js:
function SomeClass() {
// ...app logic...
// Use AnotherClass instance `a`; let's say you're going to call `foo`,
// but have no use for `bar` or `baz`
(new AnotherClass()).foo();
// ...app logic...
}
someclass-test.js:
var AnotherClass;
function someClass_testSomething() {
// Just enough AnotherClass for this specific test; there might be others
// for other tests
AnotherClass = function() {
};
AnotherClass.prototype.foo = function() { /* ...appropriate `foo` code for this test... */};
var sc = new SomeClass();
// ...test `sc`...
}
function someClass_testSomethingElse() {
// ...
}
您在实际应用中使用anotherclass.js 和someclass.js,在测试SomeClass 时使用someclass.js 和someclass-test.js。
当然,这是一个粗略的草图;我假设您的实际应用程序可能到处都没有全局变量(SomeClass,AnotherClass),但是您包含 SomeClass 和 AnotherClass 大概也可以用于包含SomeClass,并包含对其的测试及其各种假AnotherClasss。