[英]How to use a struct/interface to mock dependency for testing
我是新来这里...我的目标是对我的ready()中正在更新的状态进行单元测试。 我一直在查看https://engineering.aircto.com/writing-testable-code-in-golang/并试图弄清楚如何使他们的工作适应我的用例,填补了golang知识的空白我可以的。
我收到错误消息,无法在参数ready中将fakeSession(类型* FakeSession)用作类型* discordgo.Session,但我不确定为什么会收到此错误。
main.go
import (
"fmt"
"os"
"os/signal"
"syscall"
"github.com/bwmarrin/discordgo"
)
var (
// bot token used for this bot when connecting
token = os.Getenv("DISCORD_BOT_TOKEN")
status = os.Getenv("BOT_STATUS")
)
func main() {
// initiate Discord bot
// Register ready as a callback for the ready events.
discordConnection.AddHandler(ready)
// running the app, waiting to receive a close signal
}
// This function will be called (due to AddHandler above) when the bot receives
// the "ready" event from Discord.
func ready(session *discordgo.Session, event *discordgo.Ready) {
// Set the playing status.
session.UpdateStatus(0, status)
}
main_test.go
type FakeSession struct {
status string
idle int
}
func (f *FakeSession) UpdateStatus(idle int, game string) error {
f.idle, f.status = idle, game
return nil
}
func TestStatusIsUpdated(t *testing.T) {
readyDependency := &discordgo.Ready{}
fakeSession := &FakeSession{}
ready(fakeSession, readyDependency)
// @todo assert that idle/game status were set to correct values
}
正如@Andrew指出discordgo.Session
是一个go结构(从您发布的docs链接type Session struct {
)
structs
是go中的具体类型,无法替换。 编译器允许ready
的唯一参数是指向会话的指针。
要打破这种依赖性,您可以使用所需的方法创建由项目拥有和控制的自定义接口 。 这将使您ready
使用伪造的结构来创建和调用ready
的测试。
有时第三方库已经具有接口,因此通常值得在创建自己的godoc之前先扫描其godoc以查看哪些接口可用。
但是,如果您必须创建自己的测试文件(我发现自己经常必须这样做),则可能看起来像:
type StatusUpdater interface {
UpdateStatus(int, string)
}
// This function will be called (due to AddHandler above) when the bot receives
// the "ready" event from Discord.
func ready(s StatusUpdater, event *discordgo.Ready) {
// Set the playing status.
s.UpdateStatus(0, status)
}
现在,对discordgo.Session
的依赖已被破坏,您的测试代码可以使用其伪造的会话调用ready
函数,然后对其进行断言!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.