I have read a few questions on StackOverflow that ask how functions such as time.Now() can be mocked. The solution seems to be to write a struct that implements a particular interface, and then in the tests, pass in that mock instead.
Is there a better way of doing this? Since there is no good enough implementation of a dependency injection container in Golang, I don't want to pass structs around manually, or to create a struct that only has something like this inside:
func (s MyStruct) Now() {
return time.Now()
}
Because, first, I can't test this function. It might be nothing when you are dealing with one line that has no variables in it, but I have a function that connects to a TCP port. Doing stuff like this would require me to create adapters to everything it uses (eg net.Dial(), time.Now(), io.Copy(), bufio.Read(), and many others).
Second, since there is no DI, I will have to pass structs around, which will end up cluttering my code, rather than making it easier to read like DI does in other languages.
Besides enabling you to easily mock these functions, writing 'adapters' (your own interface) for such things has the advantage of abstracting your code from any individual implementation.
Passing structs around in your code also keeps your app from external dependencies on some kind of injection framework (many of which just violate the principle of IOC anyway).
In addition to writing your own interfaces to these dependencies, certain design philosophies can help you to mock .
For example, using domain driven design patterns, you can simply mock your "repository" in unit tests rather than mocking a database library.
In Go, all of this ends up very clean, and succinct, without the burden of a horde of third party frameworks magically doing the work for you.
Related
I'm having hard times writing unit tests in Go due to external libraries which don't expose an interface (therefore not mockable) but only pure functions. Even big ones like Google don't, so I'm wondering whether my approach is good enough.
Wouldn't be good practice for libraries to provide interfaces instead of packages with only functions in order to let the user mock them?
The solution I came up with until now is wrap these packages with an interface's implementation but that seem like too much work.
I come with an example. My function could look like this
func AnyFunction() error {
sess := session.Get("blabla")
// logic in here...
}
where session is an imported package that returns a struct. I can't mock the package session.
For this case I'm going to write a SessionInterface with an implementation, which internally calls session.
Ex:
type SessionInterface interface {
Get(s string) Session
}
type mySessionImpl struct {}
func (me *mySessionImpl) Get(s string) Session {
return session.Get(s)
}
For my tests now I can mock the SessionInterface and inject that one into my code
You're doing the right thing here, and this was a conscious decision on the part of the language designers.
The Go philosophy is that your code should "own" those interfaces, not the library. In languages like C# and Java, libraries define their interfaces up front, without really knowing what the consumer actually needs. (Maybe they include too many methods, or too few.) In Go, because the consumer effectively "owns" the interfaces, you're empowered to specify which methods actually need to be present in a minimal interface, and changes in your program requirements mean that you can also change the interface.
Now in this particular case it might seem strange to create an adapter in front of a function for testability, but consider the alternative: if session.Get() were a method of an interface or struct, instead of a function, it would force all library consumers to instantiate a dummy object in order to call the method. Not everyone is going to fake it out---it's easier for them to say that the consumers who want to (like you) are empowered to write adapters, and those that don't can blissfully ignore them.
IMO this is a super common solution and strikes a good balance between maintainability and testability.
The way I think of this is that your code is programming to an interface, and there just happens to be two implementations:
"prod" version ie the library that you're testing
test version, a stub that implements the interface
With this approach, a stub can only verify up to your service and its dependencies boundary along the contract of the interface, it assures very little or nothing about your components collaboration/integration with the library that's being stubbed. In my experiences this approach works awesome and is my personal preference. I have found it to be important though to have 1 or 2 higher level tests making sure that your component can successfully initialize and interact with the "prod" version of the library.
Plug:
I've written about this exact issue https://medium.com/dm03514-tech-blog/you-are-going-to-need-it-using-interfaces-and-dependency-injection-to-future-proof-your-designs-2cf6f58db192
I have a project I am trying to learn unit testing and TDD practices with. I'm finding that I'm getting to quite confusing cases where I am spending a long time setting up mocks for a utility class that's used practically everywhere.
From what I've read about unit testing, if I am testing MyClass, I should be mocking any other functionality (such as provided by UtilityClass). Is it acceptable (assuming that UtilityClass itself has a comprehensive set of tests) to just use the UtilityClass rather than setting up mocks for all the different test cases?
Edit: One of the things I am making a lot of setup for.
I am modelling a map, with different objects in different locations. One of the common methods on my utility class is GetDistanceBetween. I am testing methods that have effects on things depending on their individual properties, so for example a test that selects all objects within 5 units of a point and an age over 3 will need several tests (gets old objects in range, ignores old objects out of range, ignores young objects in range, works correctly with multiples of each case) and all of those tests need setup of the GetDistanceBetween method. Multiply that out by every method that uses GetDistanceBetween (almost every one) and the different results that the method should return in different circumstances, and it gets to be a lot of setup.
I can see as I develop this further, there may be more utility class calls, large numbers of objects and a lot of setup on those mock utility classes.
The rule is not "mock everything" but "make tests simple". Mocking should be used if
You can't create an instance with reasonable effort (read: you need a single method call but to create the instance, you need a working database, a DB connection, and five other classes).
Creation of the additional classes is expensive.
The additional classes return unstable values (like the current time or primary keys from a database)
TDD isn't really about testing. Its main benefit is to help you design clean, easy-to-use code that other people can understand and change. If its main benefit was to test then you would be able to write tests after your code, rather than before, with much of the same effect.
If you can, I recommend you stop thinking of them as "unit tests". Instead, think of your tests as examples of how you can use your code, together with descriptions of its behaviour which show why your code is valuable.
As part of that behaviour, your class may want to use some collaborating classes. You can mock these out.
If your utility classes are a core part of your class's behaviour, and your class has no value or its behaviour makes no sense without them, then don't mock them out.
Aaron Digulla's answer is pretty good; I'd rephrase each of his answers according to these principles as:
The behaviour of the collaborating class is complex and independent of the behaviour of the class you're interested in.
Creation of the collaborating class is not a valuable aspect of your class and does not need to be part of your class's responsibility.
The collaborating class provides context which changes the behaviour of your class, and therefore plays into the examples of how you can use it and what kind of behaviour you might expect.
Hope that makes sense! If you liked it, take a look at BDD which uses this kind of vocabulary far more than "test".
In theory you should try to mock all dependencies, but in reality it's never possible. E.g. you are not going to mock the basic classes from the standard library. In your case if the utility class just contains some basic helper methods I think I wouldn't bother to mock it.
If it's more complicated than that or connects to some external resources, you have to mock it. You could consider creating a dedicated mock builder class, that would create you a standard mock (with some standard stubs defined etc), so that you can avoid mocking code duplication in all test classes.
No, it is not acceptable because you are no longer testing the class in isolation which is one of the most important aspects of a unit test. You are testing it with its dependency to this utility even if the utility has its own set of tests. To simplify the creation of mock objects you could use a mock framework. Here are some popular choices:
Rhino Mocks
Moq
NSubstitute
Of course if this utility class is private and can only be used within the scope of the class under test then you don't need to mock it.
Yes, it is acceptable. What's important is to have the UtilityClass thoroughly unit tested and to be able to differentiate if a test is failing because of the Class under test or because of the UtilityClass.
Testing a class in isolation means testing it in a controlled environment, in an environment where one control how the objects behave.
Having to create too many objects in a test setup is a sign that the environment is getting too large and thus is not controlled enough. Time has come to revert to mock objects.
All the previous answers are very good and really match with my point of view about static utility classes and mocking.
You have two types of utilities classes, your own classes you write and the third party utility classes.
As the purpose of an utility class is to provide small set of helper methods, your utility classes or a third party utility classes should be very well tested.
First Case: the first condition to use your own utility class (even if static) without mocking, is to provide a set of valid unit tests for this class.
Second Case: if you use a third party utility library, you should have enough confidence to this library. Most of the time, those libraries are well tested and well maintained. You can use it without mocking its methods.
I'd like to brush my brain to avoid confusions. In few words, what can be said about Mocking process in TDD
What's the GREAT idea behind MOCKING?
Mocking frameworks are meant to be used only to avoid accessing DB during tests or they can be used for something else?
For new comers (like me), are all the frameworks equal or I need to choose one for this or that reason?
In addition to eliminating databases and other slow or ancillary concerns from the unit being tested, mocking allows you to start writing tests for a class without having to implement any collaborating classes.
As you design some piece of functionality, you'll realize that you need some other class or service, in order to stick to the single responsibility principle, but then you'll have to implement those to get the first one working, which in turn will demonstrate the need for still more classes.
If you can mock or stub those dependencies, then you can create the interfaces upon which that first class will rely, without actually having to implement anything outside of that class -- just return canned results from stubs of the interfaces.
This is an essential component to a test-first approach.
The GREAT idea: LIMIT THE SCOPE OF YOUR TESTS. By removing dependencies you remove the risk of test failures because of dependencies. That way you can focus on the correctness of the code that USES those dependencies.
Mocking DB's is very common but you can mock any dependency with an interface. In a recent project we mocked a web service, for example. You might even want to mock another business object just to make sure that you aren't relying on the correctness of the logic in that object.
I'd choose whichever one seems easiest to use. Moq is really nice.
I suggest you start here:
Mocks are not Stubs
It probably is the article that got me thinking the right way about Mocks. Sure the mocked object is usually heavy (otherwise it may not be worth mocking) but it doesn't have to be heavy in the sense that has some strong reliance on an external system like a database. It can be just a complex piece that you need to isolate to effectively be testing only your class and not the dependency.
I have read this: http://martinfowler.com/articles/mocksArentStubs.html
My concepts about a stub and a mock are clear. I understand the need of isolation frameworks like moq, rhinomocks and like to create a mock object. As mocks, participate in actual verfication of expectations. But why do we need these frameworks to create stubs. I would rather prefer rolling out a hand created stub and use it in various fixtures.
Have you tried using a library like Rhino Mocks for a day or two before deciding that hand-rolled stubs is a better option?
#chibacity: The whole idea about mocking libraries is to avoid implementations. If I only need to set a single property's value, I don't want to create a whole implementation of an interface. Calling code like
MyObj obj = MockRepository.GenerateStub<MyObj>();
obj.MyProperty = 33;
seems much simpler to me. Not to mention situations where I only need a dumb stub to be passed as a parameter where I don't care what happens to it (so no set up is required).
This doesn't mean you shouldn't roll out your own stubs for more complex scenarios, but in my experience such cases are rare.
My recommendation is to learn how to use a good mocking library (like Rhino) with all its little tricks, my bet is that you'll soon learn to appreciate the reasons for its existence.
Strictly speaking, no, you do not need an isolation framework to create stubs. In fact, Microsoft even has a Stubs Framework that only generates stubs, not mocks.
I've never written an isolation framework myself, but it would seem that it once you have object mocking in place, stubs would be a breeze to create. That might be the main reason that most/all isolation frameworks include stub objects.
In regards to your last sentence ("I would rather prefer rolling out a hand created stub and use it in various fixtures"), have you actually tried that on any sizable project? Sure, maybe you have an interface with a single method that returns a nullable bool -- you only have to write three stubs for that interface, and that's not so bad.
But once you start looking at dozens of interfaces and classes to stub, it simply becomes a mess to keep track of all the different stubs. If you are using each stub in several tests, you can certainly justify hand-writing a stub and putting it aside; but when you only use one particular stub once or twice, it's much easier to keep it as an "anonymous" stub directly generated by the framework, for simplicity's sake.
After using mocking frameworks for a while, I have found that my code design takes on a totally different slant. This slant seems to be directed more in an interaction style. In other words, I become more interested in messages and behavior than state. My objects become services rather than stateful objects as would happen when using stubs. With stubs I end up passing state around to other objects.
The problem for me then becomes more of creating abstraction layers. I have to question whither something should be interacting at certain levels. This helps with creating that 'Last responsible Moment'. So I end up with objects that have producers and consumers. And everything in between is just message channels.
I hope this helps.
I am trying to change my unit testing of ArcGIS, and start using mocks (I use rhino).
When I started to get into writing the tests, I noticed I have to start mocking a lot of objects, and stub a lot of methods for even a single test to pass.
For example - my controller first gets a RelationshipClass (so I need to stub the IWorkspace and the returned IRelationshipClass), then also gets an IFeature (A stub), and finally calls stubRelClass.GetRelatedObjects(stubFeature), to return an ISet of other IFeatures.
Is it normal to have to stub so many objects and methods just to make it pass? I also feel
like I really need to step over the code (yeah - I know I should have written the tests first, I am still trying this one), in order to figure out what to stub out next, and what I should return.
I am also having problem with mocking com classes which implement more than one interface. In the production code I QI them between the interfaces. How can I create a mock that implements both interfaces at runtime?
Depending on your injection chain, yes, sometimes you have to mock a lot of objects. If you're going multiple levels deep though, it may be indicative of a design fault - objects that are relying on data that is three layers down into your API may not be loosely coupled. You should be able to nip the chain in the bud by just returning a fake object of some kind at some point that has the necessary properties that the layer you're testing at needs.
You should also be able to do most of your mocking in a [SetUp] method and then have each test just change one or two things.
For mocking multiple interfaces, Rhino has the concept of a MultiMock. I believe the syntax you're after is:
var mock =
MockRepository.DynamicMultiMock<MyType>(
typeof(Interface1),
typeof(Interface2),
....);
It might be a sign of high coupling - which in turn implies a need to reduce dependencies (which will improve design and testability). As a rough guideline, an object should have around 4-6 collaborators max. Anything over that would set off my alarms.
How are Mocks meant to be used?
To me it sounds like untestable code, which is a smell :-(
I would recommend reading http://misko.hevery.com/code-reviewers-guide/. The author is coach responsible for teaching google developers in the testing area. In the article he shows how you can write testable and untestable code.
Further recommended reading:
Clean Code (Robert C. Martin) - main focus on how to write clean (which corresponds to testable) code.
Working effectively with legacy code (Michael Feather) - shows ways to get untested and untestable code under control.