MGo module testing

I have a function that takes a database *mgo.Database .

 func myFunc(db *mgo.Database) { // does some operations with db } 

I would like to write unit test and pass db in the mocked object, but it is very difficult for me to figure out how to do this with golang. In other languages, I could use the test framework there to do myMock = createMock("Class to Mock") , but with Go, I'm not sure how to do this.

I looked at gomock , but was not sure if this was the only way and was not sure how to use the mockgen tool with mgo.

I also thought that it’s possible to write an interface that has all the same methods as mgo.Database, and pass in a “finished” object that uses the interface, and then create an object that uses the interface and passes the calls to the mgo library ( similar to ORM), but it seems like a lot of coding.

+6
source share
2 answers

* mgo.Database is a pointer to a type, not an interface, you cannot make fun of it.

As in other languages, you need to provide a level of indirection so that you can provide a real object in production, but a layout for testing. So, your first step is to extract the interface that your myFunc uses (what methods it calls), then you can provide * mgo.Database during production and your layout (manual layout or using some kind of mocking structure) for testing.

This free chapter of an example from the book “The Art of Unit Testing” explains the steps you need to follow on page 52 (Chapter 3, “Using Stubs to Break Dependencies” - “3.3 Determining How Easy It Is to Test LogAnalyzer”):

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

given that in Go a type implements an interface by simply implementing interface methods - it is even simpler than in other languages ​​(e.g. C #)

so the answer is what you said

write an interface that has all the same methods as mgo.Database and pass a “mocked” object that uses the interface, and then create an object that uses the interface and passes calls through mgo's (similar to ORM), but it looks like a lot of coding .

except that you don't need to create an object that uses the interface and passes calls through to mgo library (similar to an ORM) , because * mgo.Database will implicitly satisfy your interface. So this is not much coding.

+5
source

You can also use Docker to test your device.

I created a library to help with such testing: https://github.com/skarllot/raiqub

Example: https://github.com/raiqub/data/blob/v0.4/mongostore/store_test.go

-1
source

All Articles