Javascript 在Jest中模拟外部类依赖关系
我真的很挣扎,所以请任何形式的帮助是非常感谢 我有一个导出类的ExternalDependency模块 TestSubject是另一个类模块。Javascript 在Jest中模拟外部类依赖关系,javascript,unit-testing,mocking,jestjs,Javascript,Unit Testing,Mocking,Jestjs,我真的很挣扎,所以请任何形式的帮助是非常感谢 我有一个导出类的ExternalDependency模块 TestSubject是另一个类模块。 当TestSubject将被实例化时,一个ExternalDependency实例将在此内部合成 出于测试目的,我想有选择地在ExternalDependency类的模拟版本和真实版本之间交换 ExternalDependency.js module.exports = class ExternalDependency { constructor (
当TestSubject将被实例化时,一个ExternalDependency实例将在此内部合成 出于测试目的,我想有选择地在ExternalDependency类的模拟版本和真实版本之间交换 ExternalDependency.js
module.exports = class ExternalDependency {
constructor () {
this.isMocked = false
}
}
TestSubject.js
const ExternalDependency = require('./ExternalDependency')
module.exports = class TestSubject {
constructor () {
this.externalDependency = new ExternalDependency()
}
isExternalDependencyMocked () {
return this.externalDependency.isMocked
}
}
Test.js
const TestSubject = require('./TestSubject')
const MockedExternalDependency = class ExternalDependency {
constructor () {
this.isMocked = true
}
}
describe ('TestSubject', () => {
it ('will require and instantiate the real ExternalDependency', () => {
const testSubject = new TestSubject()
expect(testSubject.isExternalDependencyMocked()).toEqual(false)
})
it ('or the mocked one here', () => {
jest.mock('./ExternalDependency', MockedExternalDependency)
// Failing with:
// babel-plugin-jest-hoist: The second argument
// of `jest.mock` must be a function.
const testSubject = new TestSubject()
expect(testSubject.isExternalDependencyMocked()).toEqual(true)
})
it ('and back to the real', () => {
jest.unmock('./ExternalDependency')
const testSubject = new TestSubject()
expect(testSubject.isExternalDependencyMocked()).toEqual(false)
})
})
好的,我知道这是错的。但是,我怎样才能达到类似的行为呢?对于任何一个正在为此奋斗的人来说…
刚刚醒来,发现了可能的解决办法 所以,首先让我们试着理解笑话是如何运作的:
// __mock__/ExternalDependency.js
module.exports = 'MOCK'
// ExternalDependency.js
module.exports = 'REAL'
// TestSubject.js
module.exports = require('./ExternalDependency')
// TestSubject.spec.js
const TestSubject = require('./TestSubject')
describe ('TestSubject', () => {
it ('will require the real ExternalDependency', () => {
expect(TestSubject).toEqual('REAL')
})
it ('or the mocked one here', () => {
jest.resetModules()
jest.mock('./ExternalDependency')
// This will work just fine:
// jest.mock('./ExternalDependency', () => {return 'MOCK'})
const TestSubjectMocked = require('./TestSubject')
expect(TestSubjectMocked).toEqual('MOCK')
})
it ('and back to the real', () => {
expect(TestSubject).toEqual('REAL')
})
})
然后解决方案应该很简单:
// __mock__/ExternalDependency.js
module.exports = class ExternalDependency {
constructor () {
this.isMocked = true
}
}
// ExternalDependency.js
module.exports = class ExternalDependency {
constructor () {
this.isMocked = false
}
}
// TestSubject.js
const ExternalDependency = require('./ExternalDependency')
module.exports = class TestSubject {
constructor () {
this.externalDependency = new ExternalDependency()
}
isExternalDependencyMocked () {
return this.externalDependency.isMocked
}
}
// TestSubject.spec.js
const TestSubject = require('./TestSubject')
const mock = () => {
return class ExternalDependency {
constructor () {
this.isMocked = true
}
}
}
describe ('TestSubject', () => {
it ('will require and instantiate the real ExternalDependency', () => {
const testSubject = new TestSubject()
expect(testSubject.isExternalDependencyMocked()).toEqual(false)
})
it ('or the mocked one here', () => {
jest.resetModules()
jest.mock('./ExternalDependency')
// This works fine too:
// jest.doMock('./ExternalDependency', mock) // you really need doMock here!
const TestSubjectMocked = require('./TestSubject')
const testSubject = new TestSubjectMocked()
expect(testSubject.isExternalDependencyMocked()).toEqual(true)
})
it ('and back to the real', () => {
const testSubject = new TestSubject()
expect(testSubject.isExternalDependencyMocked()).toEqual(false)
})
})
也可以插入类声明:
// TestSubject.js
const ExternalDependency = require('./ExternalDependency')
module.exports = class TestSubject {
constructor () {
this.externalDependency = new ExternalDependency()
}
isExternalDependencyMocked () {
return this.externalDependency.isMocked
}
isSpied() {
this.externalDependency.isSpied()
}
}
// TestSubject.spec.js
const spy = jest.fn()
const mock = (value) => {
return () => {
return class ExternalDependency {
constructor () {
this.isMocked = value
}
isSpied () {
spy()
}
}
}
}
jest.resetModules()
jest.doMock('./ExternalDependency', mock('MyMock'))
const ExternalDependencyMocked = require('./ExternalDependency')
const TestSubjectMocked = require('./TestSubject')
describe ('TestSubject', () => {
it ('tested injected', () => {
const testSubject = new TestSubjectMocked()
expect(testSubject.isExternalDependencyMocked()).toEqual('MyMock')
testSubject.isSpied()
expect(spy).toHaveBeenCalled()
})
})