单元测试mGo

K2x*_*2xL 6 unit-testing go

我有一个接受database *mgo.Database参数的函数.

func myFunc(db *mgo.Database) {
// does some operations with db
}
Run Code Online (Sandbox Code Playgroud)

我想编写一个单元测试并传入一个模拟的db对象,但是我很难搞清楚如何用golang做这个.在其他语言中,我可以使用测试框架来做一个myMock = createMock("Class to Mock"),但使用Go我不知道如何做到这一点.

我瞥了一眼gomock,但不确定这是否是唯一的方法,并且不确定如何使用mgomockgen工具.

我还想过可能编写一个接口,它具有与mgo.Database相同的所有方法,并传递一个使用该接口的"模拟"对象,然后创建一个使用该接口的对象,并将调用传递给mgo的库(类似于一个ORM),但这似乎是很多编码.

Klu*_*uyg 6

*mgo.Database是一个指向类型的指针,而不是一个接口,你不能嘲笑它.

与其他语言一样 - 您需要提供一个间接级别,以便您可以在生产中提供真实对象,但可以提供模拟测试.因此,您的第一步是提取"myFunc"使用的接口(它调用的方法),然后您可以在生产中提供*mgo.Database,并在模拟(手动模拟或使用某些模拟框架)中进行测试.

这本免费的样本章节来自伟大的书"单元测试的艺术",解释了你需要在第52页上完成的步骤(第3章"使用存根来破坏依赖关系" - "3.3确定如何轻松测试LogAnalyzer"):

http://www.manning.com/osherove/SampleChapter3.pdf

鉴于Go中的一个类型只是通过实现接口的方法来实现接口 - 它比其他语言(比如C#)更容易实现

所以答案就像你说的那样

编写一个接口,它具有与mgo.Database相同的所有方法,并传递一个使用该接口的"模拟"对象,然后创建一个使用该接口的对象,并将调用传递给mgo的库(类似于ORM),但这似乎是很多编码.

除了你不需要create an object that uses the interface and passes calls through to mgo's library (similar to an ORM)因为*mgo.Database会隐式满足你的界面.所以这不是很多编码.