How to extend Unity container for automocking? - unit-testing

I want Unity to automatically inject mocks for dependencies of SUTs in unit tests.
I'd prefer some kind of IServiceProvider implementation to customize (if needed) mocks creation.
Is it possible?
P.S. We use TypeMock

Typemock implemented something similar to what you're looking for.
Fake.Dependencies creates a real SUT object, injecting faked parameters to its longest Ctor.
Passing some of the parameters manually is also possible, the rest are automatically faked.
UnderTest real = Isolate.Fake.Dependencies<SUT>([args])
You can also get a proxy to a fake dependency later in the test.
var fake = Isolate.GetFake<F>(real);
I'm sure that implementing your own solution is also possible.

Related

Behavior of doReturn-when and when-thenReturn with mocked vs spied object

When using a spied object as test subject, If we don't want to call nested methods inside the method we are testing, Which of these (doReturn-when or when-thenReturn) can be used to mock those nested methods?
Is there a way to avoid getting invoked the real methods inside the method we are going to test?
In fact doesn't matter if you use doReturn-when or when-thenReturn method for this specific case, because considering a #Spy you will always call the real method.
You can avoid entering other methods by mocking them, but if you are using just Mockito it will be a problem (it doesn't have this approach, but PowerMock does). Particularly I disagree with this approach, because we are being too intrusive in our tests and private flow is a part of the whole flow, but you can do something like this:
SomeService mock = spy(SomeService.class);
doReturn(1).when(mock, "getNumber", ArgumentMatchers.anyInt());
For more details, you can verify PowerMock's official documentation. Also, is nice to know some basic unit testing concepts (stubs, mocks and so on).

Unit Testing mGo

I have a function that accepts a database *mgo.Database parameter.
func myFunc(db *mgo.Database) {
// does some operations with db
}
I would like to write a unit test and pass in a mocked db object, but I'm having a very difficult time figuring out how to do that with golang. In other languages I could use there testing frameworks to do a myMock = createMock("Class to Mock"), but with Go I'm not sure how to do this.
I glanced at gomock, but wasn't sure if that is the only way, and wasn't sure how to use the mockgen tool with mgo.
I also thought maybe to write an interface that has all of 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 to mgo's library (similar to an ORM), but that seems like a lot of coding.
*mgo.Database is a pointer to a type, not an interface, you can't mock 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 mock for testing. So your first step is to extract the interface that your "myFunc" uses (which methods it calls), then you can provide *mgo.Database in production and your mock (manual mock or using some mocking framework) for testing.
This free sample chapter from great book "The Art of Unit Testing" explains the steps you need to do on page 52 (chapter 3, "Using stubs to break dependencies" - "3.3 Determining how to easily test LogAnalyzer"):
http://www.manning.com/osherove/SampleChapter3.pdf
given that in Go a type implements the interface just by implementing the interface's methods - it's even easier than in other languages (like C# for example)
so the answer is as you said
to write an interface that has all of 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 to mgo's
library (similar to an ORM), but that seems 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's library (similar to an ORM) because *mgo.Database will implicitly satisfy your interface. So it's not a lot of coding.
You can use Docker on your unit testing too.
I've created a library to help this kind of testing: https://github.com/skarllot/raiqub
Example: https://github.com/raiqub/data/blob/v0.4/mongostore/store_test.go

Can I make the ninject mocking kernel and factory extensions work together?

I use ninject extensively with the factory extension. I also use moq to help with testing and in some cases (particularly complicated view models in my MVVM WPF application) I use the ninject mocking kernel to make it easier to automatically create mocks for resources required by the class under test.
In my regular product code, the ninject factory extension makes it easy to just declare an interface for the factory that looks something like this:
public interface IMyViewModelFactory
{
MyViewModel CreateMyViewModel(int recordNum);
}
and the factory extension will automatically supply an implementation which maps the creation method onto a constructor for the class while resolving any other dependencies that are constructor parameters from ninject. So If my class has a constructor that looks like this:
public MyViewModel(ILogger logger, int recordNum)
{
_logger = logger;
_recordNum = recordNum;
}
then the factory extension will create a factory method implementation that gets the ILogger from the ninject kernel and pass through my explicit parameter.
This all works great for the regular product code, but as near as I can tell I can't get this kind of thing to work in my unit tests when I'm using the mocking kernel.
Normally with the mocking kernel I set it up in the initialization method for my test class, bind a small number of interfaces to concrete classes that I want to test and then let the mocking kernel automatically supply mocks for everything else. These mocks can then be configured as needed for a particular test, and everything works great except for the factory methods. I find myself manually implementing factory methods in setup statements for my mock that look something like this:
Kernel.GetMock<IMyViewModelFactory>()
.Setup(f => f.CreateMyViewModel(It.IsAny<ILogger>(), It.IsAny<int>()))
.Returns((ILogger logger, int recordNum) =>
new MyViewModel(Kernel.Get<ILogger>, recordNum);
That way if my test needs to interact with the factory (or more likely some class I'm testing needs to use the factory to create some sub-view model) then it can actually create the instance and dependencies come from the mocking kernel so they can be setup to mock as needed.
Most of the time I love ninject and these extensions, but this is one place where the unit test setup becomes really tedious. I probably wouldn't even mind except for the fact that I'm so spoiled by how easy the factory extension makes it in my product code, and I can't figure out how to get the same benefit in my tests. Of course the above example is contrived, and sadly in many of my view models the number of dependencies and real parameters is large (and the number of view models where I have to setup this kind of thing is large), so the tedium becomes a bigger deal.
I'm hoping someone can tell me that I'm just missing something obvious and that there's a simple way to set this up.
Thanks,
Danny

Unit testing factory methods which have a concrete class as a return type

So I have a factory class and I'm trying to work out what the unit tests should do. From this question I could verify that the interface returned is of a particular concrete type that I would expect.
What should I check for if the factory is returning concrete types (because there is no need - at the moment - for interfaces to be used)? Currently I'm doing something like the following:
[Test]
public void CreateSomeClassWithDependencies()
{
// m_factory is instantiated in the SetUp method
var someClass = m_factory.CreateSomeClassWithDependencies();
Assert.IsNotNull(someClass);
}
The problem with this is that the Assert.IsNotNull seems somewhat redundant.
Also, my factory method might be setting up the dependencies of that particular class like so:
public SomeClass CreateSomeClassWithDependencies()
{
return new SomeClass(CreateADependency(), CreateAnotherDependency(),
CreateAThirdDependency());
}
And I want to make sure that my factory method sets up all these dependencies correctly. Is there no other way to do this then to make those dependencies public/internal properties which I then check for in the unit test? (I'm not a big fan of modifying the test subjects to suit the testing)
Edit: In response to Robert Harvey's question, I'm using NUnit as my unit testing framework (but I wouldn't have thought that it would make too much of a difference)
Often, there's nothing wrong with creating public properties that can be used for state-based testing. Yes: It's code you created to enable a test scenario, but does it hurt your API? Is it conceivable that other clients would find the same property useful later on?
There's a fine line between test-specific code and Test-Driven Design. We shouldn't introduce code that has no other potential than to satisfy a testing requirement, but it's quite alright to introduce new code that follow generally accepted design principles. We let the testing drive our design - that's why we call it TDD :)
Adding one or more properties to a class to give the user a better possibility of inspecting that class is, in my opinion, often a reasonable thing to do, so I don't think you should dismiss introducing such properties.
Apart from that, I second nader's answer :)
If the factory is returning concrete types, and you're guaranteeing that your factory always returns a concrete type, and not null, then no, there isn't too much value in the test. It does allows you to make sure, over time that this expectation isn't violated, and things like exceptions aren't thrown.
This style of test simply makes sure that, as you make changes in the future, your factory behaviour won't change without you knowing.
If your language supports it, for your dependencies, you can use reflection. This isn't always the easiest to maintain, and couples your tests very tightly to your implementation. You have to decide if that's acceptable. This approach tends to be very brittle.
But you really seem to be trying to separate which classes are constructed, from how the constructors are called. You might just be better off with using a DI framework to get that kind of flexibility.
By new-ing up all your types as you need them, you don't give yourself many seams (a seam is a place where you can alter behaviour in your program without editing in that place) to work with.
With the example as you give it though, you could derive a class from the factory. Then override / mock CreateADependency(), CreateAnotherDependency() and CreateAThirdDependency(). Now when you call CreateSomeClassWithDependencies(), you are able to sense whether or not the correct dependencies were created.
Note: the definition of "seam" comes from Michael Feather's book, "Working Effectively with Legacy Code". It contains examples of many techniques to add testability to untested code. You may find it very useful.
What we do is create the dependancies with factories, and we use a dependancy injection framework to substitute mock factories for the real ones when the test is run. Then we set up the appropriate expectations on those mock factories.
You can always check stuff with reflection. There is no need to expose something just for unit tests. I find it quite rare that I need to reach in with reflection and it may be a sign of bad design.
Looking at your sample code, yes the Assert not null seems redundant, depending on the way you designed your factory, some will return null objects from the factory as opposed to exceptioning out.
As I understand it you want to test that the dependencies are built correctly and passed to the new instance?
If I was not able to use a framework like google guice, I would probably do it something like this (here using JMock and Hamcrest):
#Test
public void CreateSomeClassWithDependencies()
{
dependencyFactory = context.mock(DependencyFactory.class);
classAFactory = context.mock(ClassAFactory.class);
myDependency0 = context.mock(MyDependency0.class);
myDependency1 = context.mock(MyDependency1.class);
myDependency2 = context.mock(MyDependency2.class);
myClassA = context.mock(ClassA.class);
context.checking(new Expectations(){{
oneOf(dependencyFactory).createDependency0(); will(returnValue(myDependency0));
oneOf(dependencyFactory).createDependency1(); will(returnValue(myDependency1));
oneOf(dependencyFactory).createDependency2(); will(returnValue(myDependency2));
oneOf(classAFactory).createClassA(myDependency0, myDependency1, myDependency2);
will(returnValue(myClassA));
}});
builder = new ClassABuilder(dependencyFactory, classAFactory);
assertThat(builder.make(), equalTo(myClassA));
}
(if you cannot mock ClassA you can assign a non-mock version to myClassA using new)

How to avoid duplicate code when using mocks in unittests

I am using dependency injection to supply mocks for code outside of my class under test. I find myself writing alot of the same code over and over as I need to mock out AuthProvider, ConfigurationManager, etc. which are used in the method I want to test. The method contains branches (if-then-else) and therefore I have multiple tests in place to test all execution paths of the method. I am instantiating each of the mocks several times (once in each test method) but am wondering if this is the wrong way around?
Also I am putting up expectations for the mocks and preset responses which evidently are mostly copy-paste as such calls as to AuthProvider.Authenticate() are called in every method
In each method I setup a mock repository and at the end of each method I verify the mock repository. Should I prehaps have some sort of factory for creating these mocks along with setting their expectations and return values and if so how?
For implementation of mocks I am using RhinoMocks.
"instantiating each of the mocks several times" is not a problem. Objects are free.
Just be sure you aren't defining the mock classes numerous times. Classes are expensive.
Also, you have a "setUp" method in a TestCase that allows you to create a fixture that is used by all tests. Yes, it's rebuilt for each test. No, that's not a problem unless it's painfully slow.
Assuming you're using NUnit, you can use instance variables for your Mocks and reset them in Setup/Teardown. If you see repeated patterns then do what you do with production code: refactor and extract helper methods that express what you're trying to achieve (if there's no commonality at all, then there's a problem with the design of the production code).
If there are significant divisions in setup, consider writing more than one test class for your production class.
Finally, think about whether your production class is just too busy and some of the behaviour ought to be extracted out to a helper object.
Listen to the Tests!
Here is my take..
I would not use mock in the case... I would use a factory method to return a fake implementation of the class and use dependency injection to use this implementation instead.. this way you would avoid duplication and can reuse this implementation again n again... again this factory implementation need to be refactored properly i.e., no duplication..
Mocks, I guess should be used when you are testing some dynamic behavior.. something like.. did a method in sub-system was called when I perform some action on SUT.. and later on call verify() to verify this behavior... there is also a good article on Martin Folwer bliki Mock Aren't Stubs
You might want to look at using the AAA style of test so that you have multiple tests with a common setup. Here's a decent example.
Record and Replay frameworks like EasyMock fail if you dont set an expectation on a mock call. But frameworks like Mockito simply record all calls and let you verify only the ones that matter. So you dont have to set expectation on all methods in all tests.
And coming back to your Problem of instantiating Mocks in each test method, there's a better way than using setUp() method. Mockito provides a #Mock annotation. So you declare your variables(as fields) like:
#Mock Repository repositoryMock
and just call initMocks() in setUp(). All mock objects declared are automatically available in your tests without explicitly creating Mocks.