如何解决我如何嘲笑类的依赖
我该如何模拟我正在用玩笑测试的类之一的依赖关系?
我有一个使用pigpio
模块的类
// a trimmed down version of the class and method I'm writing a test for
import { Gpio } from "pigpio"
export default class BotController {
private initializePenActuator(): void {
this.penPause = Number(process.env.PEN_PAUSE_DELAY_IN_MILLISECONDS)
this.penActuator = new Gpio(Number(process.env.PEN_ACTUATOR_PIN))
}
async setPenDirection(direction: penDirection,toggleAfterDelay?: boolean): Promise<void> {
return new Promise((resolve,reject) => {
this.penActuator.digitalWrite(direction) // the call I want to mock
if (!toggleAfterDelay) {
resolve()
}
setTimeout(() => {
resolve()
},this.penPause)
})
}
}
我正尝试为其编写以下测试:
test("can actuate with a delay",async () => {
// * actuate pen with a delay
const start: Date = new Date()
await controller.setPenDirection(penDirection.UP,true)
const end: Date = new Date()
const duration = end.getTime() - start.getTime()
// * confirm that the async call was delayed for the correct number of MS
expect(duration).toBeGreaterThanOrEqual(Number(process.env.PEN_PAUSE_DELAY_IN_MILLISECONDS))
})
但是我不确定如何为digitalWrite
的pigpio方法调用编写模拟。
我知道我可以创建一个类的模拟:
jest.mock("pigpio",() => {
return class {
digitalWrite(value) {}
}
})
但这将假定我在测试中直接调用了Pigpio类,而不是通过其他类(对吗?)。
我一直在尝试阅读有关如何正确执行此操作的文档,但是我似乎无法从示例中解析解决方案。如果不是很明显,我仍会进行测试。
我将如何模拟Pigpio,以便测试类的方法?
此外,如果您有链接到该文档中该位置的链接,那么我应该关注这一点,我将不胜感激。我不知道我是否误解了我阅读的文档,或者只是在开玩笑的文档中找不到合适的位置:|
更新
在看完Estus指出的文档中的自动模拟示例之后,我看到了如果该类是模块的默认导出,则如何模拟该类的示例。
https://jestjs.io/docs/en/es6-class-mocks#automatic-mock
但是,如果该类是模块的默认导出,则此示例有效。在我的情况下,该类不是默认导出:
如果我仅尝试模拟模块,则会收到错误消息:
如果我尝试模拟模块的Gpio类,我仍然会收到错误:
而且我似乎在文档中找不到正确执行此操作的示例:/
另一个更新
我也尝试过为Gpio
类创建一个模拟函数,模拟pigpio
模块,并为该模拟提供一个使用Gpio
模拟的实现,但仍然没有工作:
解决方法
Soooooo
我决定走依赖注入途径。我真的很想弄清楚如何模拟Gpio类,而不必走DI路线只是为了弄清楚它,但是在这一点上,我只想向前走。
对类构造函数的依赖注入
因此,依赖注入应该相对容易吧?好吧,我尝试执行的依赖项注入有一些障碍。我需要使用Gpio
类作为构造函数,而不是Gpio的实例。
在我的BotController
类中,我正在使用Gpio
类来构造Gpio
的不同实例:
但是使用typescript时,如果将类注入到构造函数中(我假设是方法),则不会得到类构造函数,而会得到该类的实例。要注入构造函数而不是实例,您需要使用typeof
:
这里我们使用typeof Greeter,即“给我Greeter类本身的类型”,而不是实例类型。或者更确切地说,“给我称为Greeter的符号的类型”,这是构造函数的类型。
所以现在,我可以模拟pigpio
模块并传递模拟的Gpio类用作构造函数,并且测试不会崩溃。
明天,继续前进!!!!
更新
您曾经爬过一座山顶,站在山顶上疲惫却得意洋洋,然后低头看向另一侧看自动扶梯吗?
发布此答案并上床睡觉后,我醒来了Estus的另一条超级有用的评论:
您错过了__esModule:对于jest.mock是true,对于命名的exports需要它。没有它,模拟将被视为CommonJS模块,转换为ESM默认导出。参见jestjs.io/docs/en/…
我在文档中什么都没有看到,但是当您查看the given section of the API reference时:
因此,借助这一新知识,我能够返回并将所有BotController代码更改回其原始状态,从而消除了依赖项注入:
在测试中,我将__esModule: true
设置重新添加到该模拟的实现中,并通过Gpio
模拟传递了我的digitalWrite
类模拟,并通过了测试:
我感觉自己已经经历过振铃,但最后我很高兴知道解决该问题的几种方法。希望这个问题和答案中的细节可以减轻别人的头痛。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。