Calling an interface method that calls another method on the same interface - unit-testing

Say I have the following interface in golang
type InterfaceA interface {
Method1()
Method2()
}
func (o *Obj) Method1() {
o.Method2()
}
func (o *Obj) Method2() {
}
obj1 := //instantiate a type that implements the above interface
If I am writing unit tests for Method1, how can I create a mock object for Obj while at the same execute code in Method1 on a real Obj object? The challenge is that Obj calls Method2 which has to be on the mocked object while Method1 needs to be called on the real object.

Go doesn't really have dynamic dispatch. The type of Method1() receiver o is *Obj so the expression o.Method2() will always call Obj.Method2(), the interface is not involved here at all.
So what you want is impossible. But that shouldn't be an issue as we normally unit-test at object level, not method level.

I am not sure, if I understand why you want to do this exactly. But You could add the "real" object as a field of the mock object and call its method.
// the mock object has a field of type Obj
type MockObject struct {
obj Obj
}
// then it can call the "real" objects method
func (o *MockObject) Method1() {
o.obj.Method2()
}
func (o *MockObject) Method2() {
}
I am doing something like this sometimes to implement an interface. For example, like below. This way I can use the server type and stick it into ListenAndServe since it implements ServeHTTP.
type Server struct {
router *http.ServeMux
}
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
s.router.ServeHTTP(w, r)
}
func NewServer() *Server {
return &Server{
router: http.NewServeMux(),
}
}
s := NewServer()
http.ListenAndServe(":8080", s)

Related

How to write mock for structs in Go

I want to write a unit test for the Transport function which will require mocking CarFactory and Car structs. See the following code:
package main
type Car struct {
Name string
}
func (h Car) Run() { ... }
type CarFactory struct {}
func (e CarFactory) MakeCar() Car {
return Car{}
}
func Transport(cf CarFactory) {
...
car := cf.MakeCar()
car.Run()
...
}
In other OOP languages like Java, C# or C++, I can just define CarFactoryMock and CarMock that extend CarFactory and Car then override MakeCar() method to return a CarMock object
class CarMock extends Car {
public Run() {...}
}
class CarFactoryMock extends CarFactory {
public Car MakeCar() { return new CarMock(); }
}
Transport(new CarFactoryMock())
How do I achieve this in Go?
Note that I can change prototype and source code of Transport function, but must keep CarFactory and Car the same since they are taken from a 3rd package
The last code snippet was about Human and Employee, which lead to confusion`.
It takes more code to mock a struct in Go than other OOP languages that support full late binding.
This code must remain untouched since its taken from a 3rd party:
type Car struct {
Name string
}
func (c Car) Run() {
fmt.Println("Real car " + c.Name + " is running")
}
type CarFactory struct {}
func (cf CarFactory) MakeCar(name string) Car {
return Car{name}
}
Since Go only supports late binding on interface, I had to make Transport receive an interface as a parameter instead of a struct:
type ICar interface {
Run()
}
type ICarFactory interface {
MakeCar(name string) ICar
}
func Transport(cf ICarFactory) {
...
car := cf.MakeCar("lamborghini")
car.Run()
...
}
And here are the mocks:
type CarMock struct {
Name string
}
func (cm CarMock) Run() {
fmt.Println("Mocking car " + cm.Name + " is running")
}
type CarFactoryMock struct {}
func (cf CarFactoryMock) MakeCar(name string) ICar {
return CarMock{name}
}
Now I can easily use the mock Transport(CarFactoryMock{}). But when I try to call the real method Transport(CarFactory{}), the go compiler shows me the following errors:
cannot use CarFactory literal (type CarFactory) as type ICarFactory in argument to Transport:
CarFactory does not implement ICarFactory (wrong type for MakeCar method)
have MakeCar(string) Car
want MakeCar(string) ICar
As the message says, MakeCar function from the interface returns an ICar, but the real MakeCar returns a Car. Go doesn't allow that. To walk around this problem I had to define a wrapper to manually convert Car to ICar.
type CarFactoryWrapper struct {
CarFactory
}
func (cf CarFactoryWrapper) MakeCar(name string) ICar {
return cf.CarFactory.MakeCar(name)
}
Now you can call the Transport function like this: Transport(CarFactoryWrapper{CarFactory{}}).
Here is the working code https://play.golang.org/p/6YyeZP4tcC.
You use an interface.
type Employee interface {
GetHuman() Human
}
type RealEmployee struct {
Company string
h Human
}
func (e RealEmployee) GetHuman() Human {
return e.h
}
// Call Hire with real employee
Hire(RealEmployee{h: RealHuman})
Hire method accepts the interface Employee, then you can write one MockEmployee struct in your tests.
func Hire(e Employee) {
...
h := e.GetHuman()
fmt.Println(h.Name)
...
}
// Mock Employee instance
type MockEmployee struct {
Company string
h Human
}
func (m MockEmployee) GetHuman() Human {
return m.h
}
// Call Hire to test with mock employee
Hire(MockEmployee{h: MockHuman})

Unit testing classes that use dagger 2 to create objects

Let's say I have a dagger 2 module as follows,
#Module
interface Creator {
MyClass create();
}
and I am using it to create an instance of MyClass
class Instantiator {
void doSomething(){
MyClass clazz = DaggerCreator.create().create();
// do things with clazz
}
}
It seems to me that I cannot effectively test the doSomething method in Instantiator because I cannot provide a mock for MyClass.
Am I wrong? If not are we supposed to use Dagger instantiation sparingly?
You are correct in saying that it is hard to test use of a Component injector, since this is a static method. But harder than what? Here is the same method using instantiation:
class Instantiator {
void doSomething(){
MyClass clazz = new MyClass();
// do things with clazz
}
}
still hard to test, right?
The point is to use as few Component (injectors) as possible and to pass in dependencies in the constructor for your objects. Dagger 2 makes resolving the dependencies in the constructor easy. This thereby makes testing easy since you can pass in mock object in a constructor.
Let's refactor the code you wrote to be testable. Assume that MyClass contains a single method, fireLazers() that you want to test is being invoked inside Instantiator's doSomething() method:
public class DoerOfSomething {
private final MyClass myClass;
#Inject
public DoerOfSomething(MyClass myClazz) {
this.myClass = myClazz;
}
public void doSomething() {
myClass.fireLazers();
}
}
Now you can write a test like this using a mock object:
public void DoerOfSomethingTest {
//mocks
MyClass mockMyClass;
//system under test
DoerOfSomething doerOfSomething;
#Before
public void setUp() {
mockMyClass = Mockito.mock(MyClass.class);
}
#Test
public void whenDoSomething_thenInteractsWithMyClass() {
//arrange
doerOfSomething = new DoerOfSomething(mockMyClass);
//act
doerOfSomething.doSomething();
//assert
verify(mockMyClass).fireLazers();
}
}
Of course, you will now need to inject DoerOfSomething into the top level class where you are injecting, but now you can be certain that the object you are injecting is functioning as expected because it is testable. Your code for using Dagger looks a bit unusual but I'll use your idioms for the sake of parity between the question and the answer.
class Instantiator {
private final DoerOfSomething doerOfSomething;
Instantiator() {
doerOfSomething = DaggerCreator.create().create();
}
void doSomething() {
doerOfSomething.doSomething();
}
}

How can I create a partial (hybrid) mock in googlemock?

Google suggests delegating calls to a parent object when you need to invoke functionality of the real object, however this does not really create a partial (hybrid) mock. When invoking the real object, any method calls are those of the real object and not the mock object, on which you may have set up actions/expectations. How do I create a partial mock that delegates only specific methods to the real object, and all other method calls to the mock object?
Delegate to real object example
using ::testing::_;
using ::testing::AtLeast;
using ::testing::Invoke;
class MockFoo : public Foo {
public:
MockFoo() {
// By default, all calls are delegated to the real object.
ON_CALL(*this, DoThis())
.WillByDefault(Invoke(&real_, &Foo::DoThis));
ON_CALL(*this, DoThat(_))
.WillByDefault(Invoke(&real_, &Foo::DoThat));
...
}
MOCK_METHOD0(DoThis, ...);
MOCK_METHOD1(DoThat, ...);
...
private:
Foo real_;
};
...
MockFoo mock;
EXPECT_CALL(mock, DoThis())
.Times(3);
EXPECT_CALL(mock, DoThat("Hi"))
.Times(AtLeast(1));
... use mock in test ...
Instead of creating an instance of the real object as a member variable, the mock should simply extend the real object, then delegate all calls to the parent by default. You can now setup your mock like normal; setting a new ON_CALL will override the default call to the parent. We let polymorphism do the work for us -- all calls, even from the parent (real) object, invoke the mock object, then the ON_CALL statement was set to invoke either the parent object or the mock behavior. We have successfully mixed real object behavior with mock behavior. This is exactly the same as delegating calls to a parent class.
Delegate to parent class example
class Foo {
public:
virtual ~Foo();
virtual void Pure(int n) = 0;
virtual int Concrete(const char* str) { ... }
};
class MockFoo : public Foo {
public:
// Mocking a pure method.
MOCK_METHOD1(Pure, void(int n));
// Mocking a concrete method. Foo::Concrete() is shadowed.
MOCK_METHOD1(Concrete, int(const char* str));
// Use this to call Concrete() defined in Foo.
int FooConcrete(const char* str) { return Foo::Concrete(str); }
};
using ::testing::Invoke;
// Create mock instance foo.
...
// Delegate to parent.
ON_CALL(foo, Concrete(_))
.WillByDefault(Invoke(&foo, &MockFoo::FooConcrete));
The only downside to this technique is that it requires a lot of boilerplate code and is sensitive to code changes. I have extended googlemock to ease this process; the code is available here. It will generate partial mocks that call the parent (real) object by default for all methods, and generate matching constructors that pass arguments to the parent constructor.
The official Google Mock guideline and also the last proposal do work however introduce a lot of boilerplate code.
So here is my proposal:
Foo.h
class Foo {
public:
virtual ~Foo();
virtual void Pure(int n) = 0;
virtual int Concrete(const char* str) { ... }
};
MockFoo.h
class MockFoo: public Foo {
using Real = Foo;
public:
MockFoo();
virtual ~MockFoo();
MOCK_METHOD1(Pure, void(int n));
MOCK_METHOD1(Concrete, int(const char* str));
};
MockFoo.cpp
MockFoo::MockFoo() {
using ::testing::Invoke;
ON_CALL(*this, Pure()).WillByDefault(Invoke([this] {return Real::Pure();}));
ON_CALL(*this, Concrete()).WillByDefault(Invoke([this] {return Real::Concrete();}));
};
MockFoo::~MockFoo() = default;
It's worth noting that having an implementation file for the mock is a good practice with observable benefits for test compilation time. Nice and easy.

How to mock a function call on a concrete object with Moq?

How can I do this in Moq?
Foo bar = new Foo();
Fake(bar.PrivateGetter).Return('whatever value')
It seems I can only find how to mock an object that was created via the framework. I want to mock just a single method/property on a concrete object I've created.
In TypeMock, I would just do Isolate.WhenCalled(bar.PrivateGetter).Returns('whatever value').
Any ideas?
You should use Moq to create your Mock object and set CallBase property to true to use the object behavior.
From the Moq documentation:
CallBase is defined as “Invoke base class implementation if no expectation overrides the member. This is called “Partial Mock”. It allows to mock certain part of a class without having to mock everything.
Sample code:
[Test]
public void FailintgTest()
{
var mock = new Moq.Mock<MyClass>();
mock.Setup(m => m.Number).Returns(4);
var testObject = mock.Object;
Assert.That(testObject.Number, Is.EqualTo(4));
Assert.That(testObject.Name, Is.EqualTo("MyClass"));
}
[Test]
public void OKTest()
{
var mock = new Moq.Mock<MyClass>();
mock.Setup(m => m.Number).Returns(4);
mock.CallBase = true;
var testObject = mock.Object;
Assert.That(testObject.Number, Is.EqualTo(4));
Assert.That(testObject.Name, Is.EqualTo("MyClass"));
}
public class MyClass
{
public virtual string Name { get { return "MyClass"; } }
public virtual int Number { get { return 2; } }
}
Only TypeMock Isolator (and perhaps Moles) can perform these stunts. Normal dynamic mock libraries can only mock virtual and abstract members.
Moles can also replace private methods as long as the types on the signature are visible. So in this case, it would look like this:
MFoo bar = new MFoo { // instantiate the mole of 'Foo'
PrivateGetterGet = () => "whatever value" // replace PrivateGetter {get;}
};
Foo realBar = bar; // retrive the runtime instance
...
If you are looking for more information on Moles, start with the tutorials at http://research.microsoft.com/en-us/projects/pex/documentation.aspx.

Parametric test with generic methods

In NUnit 2.5 you can do this:
[TestCase(1,5,7)]
public void TestRowTest(int i, int j, int k)
{
Assert.AreEqual(13, i+j+k);
}
You can do parametric test.
But I wonder whether you can do this or not, parametric test with generic test method? I.e.:
[TestCase <int>("Message")]
public void TestRowTestGeneric<T>(string msg)
{
Assert.AreEqual(5, ConvertStrToGenericParameter<T>(msg));
}
Or something similar.
Here is the quote from the release note of NUnit 2.5 link text
Parameterized test methods may be
generic. NUnit will deduce the correct
implementation to use based on the
types of the parameters provided.
Generic test methods are supported in
both generic and non-generic clases.
According to this, it is possible to have generic test method in non-generic class. How?
I don't quite understand Jeff's comment. In .net generics is both compile-time and run-time. We can use the reflection to find out the test case attribute associated with a method, find out the generic parameter, and again use reflection to call the generic method. It will work, no?
Update: OK, I now know how and hope it is not too late. You need the generic type to be in the parameter list. For example:
[TestCase((int)5, "5")]
[TestCase((double)2.3, "2.3")]
public void TestRowTestGeneric<T>(T value, string msg)
{
Assert.AreEqual(value, ConvertStrToGenericParameter<T>(msg));
}
You can make custom GenericTestCaseAttribute
[Test]
[GenericTestCase(typeof(MyClass) ,"Some response", TestName = "Test1")]
[GenericTestCase(typeof(MyClass1) ,"Some response", TestName = "Test2")]
public void MapWithInitTest<T>(string expectedResponse)
{
// Arrange
// Act
var response = MyClassUnderTest.MyMethod<T>();
// Assert
Assert.AreEqual(expectedResponse, response);
}
Here is implementation of GenericTestCaseAttribute
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class GenericTestCaseAttribute : TestCaseAttribute, ITestBuilder
{
private readonly Type _type;
public GenericTestCaseAttribute(Type type, params object[] arguments) : base(arguments)
{
_type = type;
}
IEnumerable<TestMethod> ITestBuilder.BuildFrom(IMethodInfo method, Test suite)
{
if (method.IsGenericMethodDefinition && _type != null)
{
var gm = method.MakeGenericMethod(_type);
return BuildFrom(gm, suite);
}
return BuildFrom(method, suite);
}
}
Create a private method and call that:
[Test]
public void TypeATest()
{
MyTest<TypeA>();
}
[Test]
public void TypeBTest()
{
MyTest<TypeB>();
}
private void MyTest<T>()
{
// do test.
}