Using gmock without dependency injection - c++

I'm just learning to use Google Mock. It works fine when I test a class to which I can pass the mocked object as a pointer or reference (dependency injection). When I have a class which doesn't use DI, I haven't found a solution.
We currently have a lot of code which doesn't use DI and interfaces, for example:
#include "ReadDbObjects.h"
class ObjectManager
{
public:
ObjectManager()
{
ReadDbObjects db_reader;
mObjects = db_reader.ReadAll();
}
private:
vector<MyObject> mObjects;
}
(this is extremly simplified, but should explain the problem)
We currently test something like this by creating just for the unit test a file called ReadDbObjects.cpp (which includes the original ReadObjects.h with the class declaration), which is statically linked to the unit test. In this file, we mock the ReadAll-Method, so it returns the objects we need for the test. This file is hard to maintain and it needs another file which is known both in the ReadObjects.cpp and the unit test, so values between the test and the mocked ReadObjects-class can be passed in both directions.
Is there a way to mock ReadObjects using gmock in this example?
Can gmock be used, when I need to mock a base class? Here we use the same mechanism by linking a mocked cpp base class file into the unit test.

Related

Mocking a function call inside a constructor

I have built a file manager(basically reads/writes) class I am trying to unit test. The file format basically belongs to a third party for which I have third party function calls in the constructor. I call all third party calls through wrapper methods
My question is this: Before starting to unit test any method in the class I am trying to instantiate the constructor which looks something like this:
Filemanager::Filemanager{
if(wrapperfoo()){
file->open() //for writing
}
initialise();
}
Now I have a mock class MockManager to mock Filemanager. When I am trying to instantiate MockManager,
I need to mock wrapperoo to return true. However, since the manager itself is not instantiated yet, the EXPECT_CALL fails. Since the EXPECT_CALL has to be placed before the new MockManager()
MockManager *mgr;
EXPECT_CALL(*mgr, wrapperfoo()).Return(true) // Crashes here.. Obviously!!
mgr = new MockManager();
How can I handle this case?
I see no chance for this to work, you are forced to build yourself a workaround. You already gave the explanation yourself.
In principle, mocking isn't designed for what you want to achieve, it is designed for testing components in their behavior to an API or interface, where you mock the interface (API) for the component and not vice versa (https://www.youtube.com/watch?v=dLB2aDasVTg&list=PL_dsdStdDXbo-zApdWB5XiF2aWpsqzV55&index=4, very good explanation). In this example you wouldn't use mocking for internal calls (from the contructor), rather in the test case of another component that requests to get the return type from wrapperfoo().

Mocking a file write process in googlemock

I am just starting with mocking using googlemock for a C++ project. In my case, my class to be tested observes a file that is written to, and whenever a minimal amount of new data has been written, it starts doing some work.
What I need is a mock class for the process writing to the file. As far as I understand things, I need to completely implement this "writing to file" functionality in form of (for googlemock) a virtual class from which a mock class is derived? The mock wrapper is finally used for testing and evaluation purposes, right?
Thanks for help!
Mocks, in google mock terms, are objects used to validate that your code under test performs certain operations on them.
What you describe is not a mock, but a utility class that triggers your code under test operations.
What does your class do when it detects that the file it observes is written to? If, for instance, it performs a call to another object, then you could use a mock object to check that it gets called with the right parameters, e.g. the new bulk of data written to the file.
I am assuming that an object of your "observer" class is notified
that minimal amount of data has been written by an object of
the "writter" class. In that case, you need to implement an abstract
class that represents an interface for your "writter" class, and have
your real "writter" class inherit from it and override its virtual functions.
Also, have your mock "writter" class implementation inherit from this interface and
and create mock implementations using MOCK_METHODn.
Then, have your "observer" class receive notifications from "writter" object
using a pointer to the abstract class. This way, you can use dependency
injection to switch implementation during testing phase by creating a mock
"writter" object and passing its address to "observer" object (instead of an address to a real "writter"
object) and setup test cases using EXPECT_CALL on the mock object.
This is the best advice I can give since you did not provide us with a detailed description of your classes.
EDIT:
Concerning the implementation of your real "writter" class: You do not have to create it immediately, you can use the mock class for now to test the behavior of the "observer" class and leave the implementation for later. You will, of course, have to implement it eventually since it has to be used in production code.

Unit Testing with Rhino Mocks

I have the following method called Execute() from the Abstract class called AutoLetterGenBatch in my ConsoleApp. I am trying to unit test this.
public void Execute()
{
BatchJobSecurity.Instance.CreatePrincipal();
DoExecute();
}
So I set up what I believe are all the proper references and try to invoke the method like below .
[TestMethod]
public void TestMethod1()
{
AutoLetterGenBatchJob ALGBJ = new AutoLetterGenBatchJob();
ALGBJ.Execute();
}
However, when I go to do the build it gives me this compilation error Error 34 Cannot create an instance of the abstract class or interface 'AutoLetterGenBatch.AutoLetterGenBatchJob' .
I am somewhat new to unit testing. I realize this probably isn't much of a test but I just want to see my Execute() method get hit for the time being. I have read that a good way to get around this problem with abstract classes is to set up a mock object for the abstract class. So I try to do this with RhinoMocks.
[TestMethod]
public void TestMethod1()
{
AutoLetterGenBatchJob ALGBJ = MockRepository.GenerateStub<AutoLetterGenBatchJob>();
ALGBJ.Execute();
}
It now builds with all of the proper using statements in place. However when the test runs I now get this error. Can't find a constructor with matching arguments . Again I am pretty new to this. If someone can help me to understand what it is I need to do it would be appreciated.
YOur first test doesn't make any sense, your class is abstract, by definition you can't create an instance of it. In order to test that method you need a class which derives from AutoLetterGenBatch and you then create an instance of this class and do what is neccessary to invoke the method on this instance.
Using a mocking framework would be one way, as would creating a test class of your own. Personally I would go with the 'roll your own' at first as this will be easier to debug.
public class TestAutoLetterGenBatch : AutoLetterGenBatch
{
}
once you have this class you'll see that you need to call the constructor that AutoLetterGenBatch declares. This is the same issue that rhino mocks it complaining about. Without seeing the class AutoLetterGenBatch we can't advise any further.
For what it is worth, Rhino mocks has seen little work recently and you would probably be better using Moq or another more active framework.
Also you need to generate a partial mock to do the testing you want to do, no a stub.

Mocking internal classes with Moq for unit testing

Say I have a class "ClassA", which has a dependency on a class "ClassB" (injected into the constructor of ClassA). I want to mock ClassB so that I can test ClassA in isolation. Both classes are internal.
Correct me if I'm wrong but it looks like Moq can only mock a class if it is public, it has a public parameterless constructor, and the methods to be mocked are public virtual. I don't really want to make these classes publicly visible. Am I missing something with Moq, or is it just not suitable for what I want to do?
I guess I could create an interface (say "IClassB") that ClassB implements, inject that into ClassA, and mock the interface instead. ClassB can still be internal (although I realise the interface methods would have to be public). While this would work, I feel uneasy about creating lots of interfaces, whose only purpose is to support unit test mocking. Thoughts?
You could make internals visible to Moq by adding InternalsVisibleToAttribute in your project's assembly.cs, like this:
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
Why "DynamicProxyGenAssembly2" and not "Moq"? It's the name of dynamic assembly created to contain dynamically generated proxy types (all of this is handled by yet another library, Castle's DynamicProxy) which is used by Moq. So you expose types to dynamic proxy assembly, not to Moq itself.
But, what's the point of mocking class if there's no overridable member? You won't mock anything and all calls will use actual implementation. Your second solution,
I guess I could create an interface (say "IClassB") that ClassB implements, inject that into ClassA, and mock the interface instead.
is what I would normally do. Its purpose is much more than "to support unit test mocking" - it helps you build losely coupled components, which is always something worth aiming for.
Also, you can add this into .csporj file.
<ItemGroup>
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
<_Parameter1>DynamicProxyGenAssembly2</_Parameter1>
</AssemblyAttribute>
</ItemGroup>

Dependency Injection: Turtles all the way down?

So I'm wondering about how unit testing works in regards to dealing external dependencies. Here and elsewhere I've become familiar with dependency injection, and how that allows us to test a unit (A) of code. However, I'm confused about how to test other units (B and C) which are now possess the external dependency so they can inject it into the original unit (A).
For example, say some class Foo uses an external dependency...
class Foo
{
private ExternalDependency ed;
public int doSomethingWithExternalDependency() {...}
}
And class Bar makes use off Foo...
class Bar
{
public int doSomethingWithFoo
{
Foo f = new Foo();
int x = f.doSomethingWithExternalDependency();
// Do some more stuff ...
return result;
}
}
Now, I know that I can use dependency injection so that I can test Foo, but then how do I test Bar? I guess, I can, again, use dependency injection, but at some point some unit needs to actually create the external dependency; so how do I test that unit?
The examples you provide do not use Dependency Injection. Instead, Bar should use Constructor Injection to get a Foo instance, but there's no point in injecting a concrete class. Instead, you should extract an interface from Foo (let's call it IFoo) and inject that into Bar:
public class Bar
{
private IFoo f;
public Bar(IFoo f)
{
this.f = f;
}
public int doSomethingWithFoo
{
int x = this.f.doSomethingWithExternalDependency();
// Do some more stuff ...
return result;
}
}
This enables you to always decouple consumers and dependencies.
Yes, there will still be a place where you must compose the entire application's object graph. We call this place the Composition Root. It's a application infrastructure component, so you don't need to unit test it.
In most cases you should consider using a DI Container for that part, and then apply the Register Resolve Release pattern.
Keep in mind the difference between unit testing and integration testing. In the former, the dependency would be mocked whereby it provides expected behavior for the purpose of testing the class which consumes the dependency. In the latter, an actual instance of the dependency is initialized to see if the whole thing works end-to-end.
In order to use Dependency Injection, your classes would have their dependencies injected into them (several ways to do that - constructor injection, property injection) and would not instantiate them themselves, as you do in your examples.
Additionally, one would extract the interface of each dependency to help with testability and use the interface instead of an implementation type as the dependency.
class Foo
{
private IExternalDependency ed;
public int doSomethingWithExternalDependency() {...}
public Foo(IExternalDependency extdep)
{
ed = extdep;
}
}
What most people do is use a mocking framework to mock the dependencies when testing.
You can mock any object that the class under test depends on (including behavior and return values) - pass the mocks to the class as its dependencies.
This allows you to test the class without relying on the behavior of its (implemented) dependencies.
In some cases, you may want to use fakes or stubs instead of a mocking framework. See this article by Martin Fowler about the differences.
As for getting all the dependencies, all the way down - one uses an IoC container. This is a registry of all of the dependencies in your system and understands how to instantiate each and every class with its dependencies.
When you unit test a class, you should mock its dependencies, to test your class in isolation -- this is regardless of dependency injection.
The answer to your question about Bar is: yes, you should inject Foo. Once you go down the DI path, you will use it across your entire stack. If you really need a new Foo for every doSomethingWithFoo call, you might want to inject a FooFactory (which you can then mock for testing purposes), if you want a single Bar to use many Foos.
I'd like to stress out that in case of unit testing you should have two separate sets of tests: one for Foo.doSomethingWithExternalDependency and another one for Bar.doSomethingWithFoo. In the latter set create mock implementaion of Foo and you test just doSomethingWithFoo assuming that doSomethingWithExternalDependency works properly. You test doSomethingWithExternalDependency in a separate test set.