[英]How to use a struct/interface to mock dependency for testing
I'm new to go here... my objective is to unit test that a status is being updated in my ready(). 我是新来这里...我的目标是对我的ready()中正在更新的状态进行单元测试。 I've been looking at https://engineering.aircto.com/writing-testable-code-in-golang/ and trying to figure out how to adapt what they're doing to my use case, filling in gaps of golang knowledge where I can.
我一直在查看https://engineering.aircto.com/writing-testable-code-in-golang/并试图弄清楚如何使他们的工作适应我的用例,填补了golang知识的空白我可以的。
I'm getting the error cannot use fakeSession (type *FakeSession) as type *discordgo.Session in argument to ready but I'm not sure why I'm getting this error. 我收到错误消息,无法在参数ready中将fakeSession(类型* FakeSession)用作类型* discordgo.Session,但我不确定为什么会收到此错误。
main.go 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 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
}
As @Andrew pointed out discordgo.Session
is a go struct (from the docs link you posted type Session struct {
) 正如@Andrew指出
discordgo.Session
是一个go结构(从您发布的docs链接type Session struct {
)
structs
are Concrete types in go and are unable to be substituted. structs
是go中的具体类型,无法替换。 The only argument go compiler will allow for ready
is a pointer to a session. 编译器允许
ready
的唯一参数是指向会话的指针。
To break this dependency you can create a custom interface owned and controlled by your project using the methods that you need. 要打破这种依赖性,您可以使用所需的方法创建由项目拥有和控制的自定义接口 。 This will allow you to create and call
ready
with a fake structure for your tests. 这将使您
ready
使用伪造的结构来创建和调用ready
的测试。
Sometimes 3rd party libraries already have interfaces so it's usually worth-while to scan their godoc to see which interfaces are available before creating your own. 有时第三方库已经具有接口,因此通常值得在创建自己的godoc之前先扫描其godoc以查看哪些接口可用。
But if you have to create your own for testing (and I find myself regularly having to do this), it might look like: 但是,如果您必须创建自己的测试文件(我发现自己经常必须这样做),则可能看起来像:
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)
}
Now the dependency on discordgo.Session
has been broken, and your test code can call ready
function with its fake session, and then make assertions on it! 现在,对
discordgo.Session
的依赖已被破坏,您的测试代码可以使用其伪造的会话调用ready
函数,然后对其进行断言!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.