我有一个利用辅助类的类,我想验证它是否正确构造了这些对象。所以,我正在尝试在我的类中存根“构造函数”方法,但我显然没有做到这一点:
"use strict";
class Collaborator {
constructor(settings) {
console.log("Don't want this to be called!")
this.settings = settings;
}
}
class ThingToTest {
constructor(settings) {
this.helper = new Collaborator(settings);
}
}
const assert = require("assert");
const sinon = require("sinon");
describe("ThingToTest", () => {
let settings = "all the things"
context("spying on constructor", () => {
let spy = sinon.spy(Collaborator, "constructor")
after(() => spy.restore())
describe("constructor", () => {
it("creates a Collaborator with provided settings", () => {
new ThingToTest(settings);
sinon.assert.calledWith(spy, settings)
})
})
})
context("spying on prototype constructor", () => {
let spy = sinon.spy(Collaborator.prototype, "constructor")
after(() => spy.restore())
describe("constructor", () => {
it("creates a Collaborator with provided settings", () => {
new ThingToTest(settings);
sinon.assert.calledWith(spy, settings)
})
})
})
context("stub constructor", () => {
before(() => {
sinon.stub(Collaborator, "constructor", (settings) => {
console.log("This should be called so we can inspect", settings);
})
})
after(() => { Collaborator.constructor.restore() })
describe("constructor", () => {
it("creates a Collaborator with provided settings", () => {
new ThingToTest(settings);
})
})
})
context("stub prototype constructor", () => {
before(() => {
sinon.stub(Collaborator.prototype, "constructor", (settings) => {
console.log("This should be called so we can inspect", settings);
})
})
after(() => { Collaborator.prototype.constructor.restore() })
describe("constructor", () => {
it("creates a Collaborator with provided settings", () => {
new ThingToTest(settings);
})
})
})
})
运行它会产生这些(不合需要的)结果:
ThingToTest
spying on constructor
constructor
Don't want this to be called!
1) creates a Collaborator with provided settings
spying on prototype constructor
constructor
Don't want this to be called!
2) creates a Collaborator with provided settings
stub constructor
constructor
Don't want this to be called!
✓ creates a Collaborator with provided settings
stub prototype constructor
constructor
Don't want this to be called!
✓ creates a Collaborator with provided settings
似乎存根是有点工作,因为在间谍测试错误之前将存根测试与可怕的“TypeError:尝试包装已经包装的构造函数”。因此,清楚地弄清楚如何模拟Collaborators构造函数只是我做错的一半。 。 。我也没有正确恢复构造函数。有什么建议吗?
答案 0 :(得分:0)
这是不是我想要的解决方案,但是暂时我可能最终会使用这个(但是,如果你有建议,请告诉我自己):
context("checking Collaborator in a more integration style test", () => {
describe("constructor", () => {
it("creates a Collaborator with provided settings", () => {
let thing = new ThingToTest(settings);
assert.equal(thing.helper.settings, settings)
})
})
})
这会传递并验证Collaborator是否设置了正确的设置。但是现在如果我想重构Collaborator构造函数,我将打破ThingToTest。再一次,我仍然希望有人可以建议一种方法来实际测试这门课程!
答案 1 :(得分:0)
不确定这是我的最终答案,但我最终使用了proxyquire,因为它是我迄今为止找到的最佳解决方案。为了说明它是如何工作的,我将测试中的类分成了自己的目录,并将测试文件分成了一个子项" test"目录。这说明了如何在proxyquire工作中的路径(这花了我一些时间来弄清楚)。所以,这就是我最终的结果:
/Collaborator.js
"use strict"
class Collaborator {
constructor(settings) {
console.log("Don't want this to be called!")
this.settings = settings;
}
}
module.exports = Collaborator
/ThingToTest.js
"use strict"
const Collaborator = require("./Collaborator")
class ThingToTest {
constructor(settings) {
this.helper = new Collaborator(settings)
}
}
module.exports = ThingToTest
/test/ExampleTest.js
"use strict";
const proxyquire = require('proxyquire')
const mockCollaborator = sinon.stub();
const ThingToTest = proxyquire("../ThingToTest", { "./Collaborator" : mockCollaborator })
const assert = require("assert");
const sinon = require("sinon");
describe("ThingToTest", () => {
let settings = "all the things"
context("checking Collaborator in a more integration style test", () => {
describe("constructor", () => {
it("creates a Collaborator with provided settings", () => {
let thing = new ThingToTest(settings);
assert.equal(mockCollab.firstCall.calledWith(settings))
})
})
})
})
请注意proxyquire("../ThingToTest", { "./Collaborator" : mockCollaborator })
内的路径如何匹配" ThingToTest"使用,不来自测试类的路径。我希望这有助于其他人,但我仍然愿意接受其他想法和建议!