How to test a method that calls another class' method? - unit-testing

I'm fairly new to unit testing. I've recently encountered a problem where I test a method that does one thing only - it calls a method of an object that's part of the class. The class that this object represents has it's own unit tests.
I understand that this method may change in time, and when it does the test should inform me about if the expected result it. But what can I test in such a method?
My code:
public class MyClassToBeTested
{
private CustomType myObject;
private const myParameter = 2;
(...)
public string MyProperty
{
get
{
return myObject.DoYourStuff(myParameter);
}
}
}

This sounds like you need to capture the call to the underlying object and inspect it (or at least verify that the call has been made). I would mock this object and inject a reference to it (Inversion of Control).
By injecting the object you can provide the real object at deploy time, and the mock during testing.

If something is dependent on something else. i.e. method calls another method, then you should mock it, or simulate its behaviour.

Related

Gmock const method not called instead calling the original method

I have interface which is defined as
in .h file
namespace diagnostic{
class class1interface{
virtual int readpowerstate()const =0;
virtual int readparameters() = 0;
}
class class1 : public class1interface{
int readpowerstate()const;
int readparameters();}};
in .cc file i have the function
int diagnostic::readparameters(){
if(diagnostic::readpowerstate ==1)
{ //Dothis}
else
{return 0}}
i have to execute the else part since by default the if will get called when i run the program. So i tried to use gmock as follows.
class Mock_class : public diagnostic::class1interface{
public:
Mock_class(){}
MOCK_METHOD0(readparameters,int());
MOCK_CONST_METHOD0(readpowerstate,int());};
and the gmock test i wrote as follows
// Test the failure of Read Parameters
TEST_F(TestBase, readParam_failure){
Mock_class mock_class;
class1 *class_dummmy = new class1();
EXPECT_CALL(mock_class, readpowerstate()).WillOnce(Return(0));
class_dummy->readparameters;
EXPECT_EQ(0, class_dummy->readparameters());}
when i'm executing this program i'm getting the error that
error: Actual function call count doesn't match
EXPECT_CALL(mock_class, readpowerstate())...
Expected: to be called at least once
Actual: never called - unsatisfied and active
what is the solution for this since i'm new to gmock.
Module tests are all about testing an isolated module (like an instance of a selected class) in a mocked environment, specifically, how that module communicates with other objects, and how it responds to various results of these calls. To make this possible, one uses mocks in place of that other real objects. Mock classes allow to both:
configure expectations regarding, e.g., the amount/sequence of calls and/or the values of arguments of these calls to specific functions, and verify those by registering all interactions;
program the results of these expected calls that are returned as if a real object performed some action and responded to the object under test.
This makes it possible to test an object as if it were surrounded by real components, without actually having those. E.g., a device manager can be tested on how it responds to device failures, by mocking a class representing a device and programming that mock to return an error code when some status function is invoked by the manager. That is, no real device class is used, and also, no real (faulty!) device itself is needed to be connected and configured. The mock will pretend to be that device, and what's important, this will all be on a software level.
This, however, is possible only if the class itself is designed in a way that allows us to somehow inject mocked objects in place of their real counterparts. Most importantly, the objects in the system need to communicate via interfaces and virtual calls. That is, the aforementioned device manager should not be communicating with, e.g., DeviceA (a concrete class name), but instead, some DeviceInterface, and so both DeviceA and a newly created mock DeviceMock could implement that interface and be used in that manager. This way the manager will not even know that it is beeing tested and communicates with a mocked object, and not the real device wrapper.
That is, currently, although you create a mock for class1interface you don't actually use that mock. Instead, you try to test class1. Creating a mock for class1interface is useful only if you aim to test some other component (like a class) that communicates with class1 through class1interface, not class1 itself.
So, having a mock for class1, you can e.g. test class2. But this requires this class design to meet the conditions I mentioned previously: communicating via interfaces and ability to inject a mock class.
So to meet the conditions, you'd have to rewrite the code:
int class2::readdata()
{
std::unique_ptr<diagnostic::class1interface> classint
= std::make_unique<diagnostic::class1>();
int value = classint->readparameters();
return value;
}
to (it's just an example of questionable usefulness, you'd have to adjust it to your needs):
int class2::readdata(diagnostic::classinterface* classint)
{
int value = classint->readparameters();
return value;
}
And so you could write a test for class2, injecting a mock of class1:
TEST_F( TestClass2, readParam_failure )
{
// Mocks configuration
Mock_class mock_class;
EXPECT_CALL( mock_class, readparameters() ).WillOnce(Return(0));
// System under test configuration
diagnostic::class2 sut;
// Test itself
EXPECT_EQ( 0, sut.readdata(&mock_class) );
}
This way you check that the call to class2::readdata is properly fowarded to class1interface::readparameters, and its result is returned.

What should be the strategy for Unit testing a method calling other methods in the same class?

I am writing unit tests for a class that has a method that calls other methods of the same class. This is leading to a lot of scenarios to be tested.
I am of the opinion that I can spy() the behaviour of the method calls so that I am testing only the method under test and not bothered about other methods behaviour. I will cover them through a separate test for each of those methods.
class MyClass{
public void myMethodToBeTested(){
aPrivateMethod();
aPublicMethod();
}
private void aPrivateMethod(){
// doing something
// Has some if else scenarios
}
public void aPublicMethod(){
// doing something
// Has some if else scenarios
}
}
What would be best way to unit test this class?
You should test by calling the external interface of the class i.e. the public methods.
If those methods call private methods in the same class, then those private methods need to be fully covered too - otherwise how would they be tested?
Stubbing or spying only makes sense for calls to resources or classes outside the class under test.
You're trying to test the entire class, not just individual methods.
In my view the aPrivateMethod could go to a separate class as public and also the body of the aPublicMethod could be a different method in that class.
After this refactoring you can inject the new class and call those methods in the corresponding places.
When it comes to testing, you could mock/stub those methods and test the myMethodToBeTested().
First off, I'd change the private method to default / package-level. That way, a unit test occupying the same package can access it but other methods, outside of that package, can't touch it. Not quite the same thing as private scope, but close enough most of the time.
Then, setup a Spy() on MyClass.
In case you're not clear on that term:
A Mock() on a class will always return null or 0 to any method call
A Stub() on a class lets you define what certain methods in that class should do, but anything you DON'T explicitly specify always returns a null or 0
A Spy() lets you create an object of a class, with all methods in place EXCEPT you can override some of those methods
So create a Spy(MyClass), specify what aPrivateMethod() and aPublicMethod() should return for testing purposes then call myMethodToBeTested() and see what is returned. In your example, that method is void, so it doesn't return anything. But you can always:
define a variable outside of the Spy()
have aPublicMethod() set / modify the variable based on inputs or internal state (your overriding methods in your Spy() can take parameters)
call myMethodToBeTested()
check the contents of that variable

Rhino Mock Expect.Call() actually calls the method not only create an expectation

I want to test if a method has been called in the test.
My problem is that when I want to create the expectations it is not working as I thought. The next line actually runs the method, not only create an expectation:
Expect.Call(() => mockedService.MethodThatIExpectToRun(params));
There is another way:
mockedService.Expect((s=> s.MethodThatIExpectToRun(params)));
But this also actually runs the method, not only creates an expectation to be fulfilled by the test.
And this line that asserts if the method was not called also actually calls the method, not only checks whether it was called.
mockedService.AssertWasCalled(s=> s.MethodThatIExpectToRun((params)));
additional info:
MethodThatIExpectToRun returns void
For prgmtc's comment:
IService mockedService = MockRepository.GeneratePartialMock<Service>(mockedRepository_1, ..., mockedRepository_n);
Usually when you have PartialMock that's calling the real method when setting a Stub or Expect, it means the virtual keyword is missing on the method.
Make sure Service.MethodThatIExpectToRun is virtual.
A more general (although perhaps less useful) remark: Partial mocks can point to a design smell of the code under test. If you only want to provide expectations for a part of a class, then perhaps that class has too many responsibilities and should be split into multiple classes? That way you can cleanly isolate responsibilities/collaborators and have no need for the partialmock construct. If you mock (not partial mock) an interface or virtual member of a concrete class the call won't go through to the real implementation.
For example:
Console.WriteLine("Real object: ");
new Foo().Bar();
Console.WriteLine("Mocked object: ");
var aFoo = MockRepository.GenerateMock<Foo>();
aFoo.Expect(f => f.Bar());
aFoo.Bar();
...
public class Foo
{
public virtual void Bar()
{
Console.WriteLine("REAL IMPLEMENTATION");
}
}
Outputs:
Real object:
REAL IMPLEMENTATION
Mocked object:

Mocking vs. Spying in mocking frameworks

In mocking frameworks, you can mock an object or spy on it. What's the difference between the two and when would/should I use one over the other?
Looking at Mockito, for example, I see similar things being done using spies and mocks, but I am unsure as to the distinction between the two.
Mock object replace mocked class entirely, returning recorded or default values. You can create mock out of "thin air". This is what is mostly used during unit testing.
When spying, you take an existing object and "replace" only some methods. This is useful when you have a huge class and only want to mock certain methods (partial mocking). Let me quote Mockito documentation:
You can create spies of real objects. When you use the spy then the real methods are called (unless a method was stubbed).
Real spies should be used carefully and occasionally, for example when dealing with legacy code.
When in doubt, use mocks.
I'll try to explain using an example here:
// Difference between mocking, stubbing and spying
#Test
public void differenceBetweenMockingSpyingAndStubbing() {
List list = new ArrayList();
list.add("abc");
assertEquals(1, list.size());
List mockedList = spy(list);
when(mockedList.size()).thenReturn(10);
assertEquals(10, mockedList.size());
}
Here, we had initial real object list, in which we added one element and expected size to be one.
We spy real object meaning that we can instruct which method to be stubbed. So we declared that we stubbed method - size() on spy object which will return 10, no matter what is actual size.
In a nutshell, you will spy real object and stub some of the methods.
Mockito warns that partial mocking isn't a good practice and you should revise your Object Oriented architecture. Spy (or partial mocking) is recommended to test legacy code.
Based on Mocks Aren't Stubs by Martin Fowler:
Dummy objects are passed around but never actually used. Usually they are just used to fill parameter lists.
Fake objects actually have working implementations, but usually take some shortcut which makes them not suitable for production (an in memory database is a good example).
Stubs provide canned answers to calls made during the test, usually not responding at all to anything outside what's programmed in for the test.
Spies are stubs that also record some information based on how they were called. One form of this might be an email service that records how many messages it was sent.
Mocks are what we are talking about here: objects pre-programmed with expectations which form a specification of the calls they are expected to receive.
In Mockito if you assign any object to instance variable of Mock Object then does not affect on Mock Object.
But in case of Spy, if you assign any object to instance variable of Spy Object then does affect on Spy Object because of Spy act like real-time object modification.
For a reference example are
#RunWith(MockitoJUnitRunner.class)
public class MockSpyExampleTest {
#Mock
private List<String> mockList;
#Spy
private List<String> spyList = new ArrayList();
#Test
public void testMockList() {
//by default, calling the methods of mock object will do nothing
mockList.add("test");
assertNull(mockList.get(0));
}
#Test
public void testSpyList() {
//spy object will call the real method when not stub
spyList.add("test");
assertEquals("test", spyList.get(0));
}
}
Reference: http://javapointers.com/tutorial/difference-between-spy-and-mock-in-mockito/
When using mock objects, the default behavior of the method when not stub is do nothing. Simple means, if its a void method, then it will do nothing when you call the method or if its a method with a return then it may return null, empty or the default value.
While in spy objects, of course, since it is a real method, when you are not stubbing the method, then it will call the real method behavior. If you want to change and mock the method, then you need to stub it.
Spies have two definitions. One, is where the real method is called, another where, no functionality is called and only null or null equivalent values are returned, but methods were called, and they're state was recorded, commonly like, method x was called y times.
If we want to avoid calling external services and just want to test the logic inside the method then use mock.
If we want to call the external services and use the real dependency i.e to run the program as it is and just stub specific methods then use spy

Unit Testing: TypeMocking a singleton

I'm using TypeMock Isolater to mock up some objects for some unit tests - attempting to use the AAA api (so the Isolate calls).
I have a straightforward singleton class where you call a static GetInstance(), which then returns an instance of the class. I thought it would be a simple matter of mocking that up, but I'm running into a very frustrating problem ! I can't seem to make GetInstance() return my mocked object correctly with my expected calls set.
I've tried:
using MST projects (using the Accessor classes) to assign a mocked object directly to the instance variable (faking the object using Memers.MustSpecifyReturnValues, and Isolate.WhenCalled using WithExactArguments to set expectations), but for some reason the mocked object always returns null (and no exceptions).
Mocking Singleton.GetInstance() to return the mocked object. This returns a mocked object which needs WhenCalled set, but now the Isolate.WhenCalled calls I make seem to do nothing on the fake object - so all calls throw an unexpected call exception.
I've also tried mocking the actual method call (eg Singleton.GetInstance().Test()), which will work for the call to that method, but all other calls to other methods on the singleton return null rather then throw an exception as I want it to (because this seems to automatically mock up all the objects without Members.MustSpecifyReturnValues).
All I want is to mock a singleton, and any calls I don't explicitly tell it to expect to throw an exception on. I thought it would be simple, but apparently not ! Sad
Has anyone any idea what I'm doing wrong?
Thanks
James
I think the simple solution will be to create a fake instance of the singleton class and use SwapNextInstace before the actual class constructor is called:
[TestMethod]
public void SetBhaciorOnSingleton()
{
var fake = Isolate.Fake.Instance<SingletonClass>();
Isolate.WhenCalled(() => fake.SomeFunction()).WillReturn(10);
// Set additional behavior on singleton class
Isolate.Swap.NextInstance<SingletonClass>().With(fake);
// This is where the class constructor is being called
var result = SingletonClass.GetInstace().SomeFunction();
Assert.AreEqual(10, result );
}
This solution should work with most scenarios unless the singleton class is created before the test.
If you need to set behavior after the class was created just use WhenCalled:
[TestMethod]
public void SetBhaciorOnSingleton()
{
var fake = Isolate.Fake.Instance<SingletonClass>();
Isolate.WhenCalled(() => fake.SomeFunction()).WillReturn(10);
Isolate.WhenCalled(() => SingletonClass.GetInstace()).WillReturn(fake);
var result = SingletonClass.GetInstace().SomeFunction();
Assert.AreEqual(10, result );
}
Disclaimer I work at Typemock.
You don't need to mock Singleton.GetInstance<>(). Using Isolate.Fake.AllInstances<>() instead of Isolate.Fake.Instance<>() you can mock the singleton. Then by setting the behavior on fake singleton behavior applied to all instances.
Take a look on the example:
public class Singleton
{
private Singleton() { }
static readonly Singleton instance = new Singleton();
public static Singleton Instance { get { return instance; } }
public int ReturnZero()
{
return 0;
}
}
[TestMethod]
public void FakeSingleton()
{
// Here we are setting the same behavior on all instances.
// The behavior we set on fake will apply to past instance as well
var fakeSingleton = Isolate.Fake.AllInstances<Singleton>();
Isolate.WhenCalled(() => fakeSingleton.ReturnZero()).WillReturn(10);
// Assert that the behavior works.
Assert.AreEqual(10, Singleton.Instance.ReturnZero());
}
Thanks.
I didn't try NextInstance before because it doesn't work on interfaces which I didn't really want to change.
But, I've tried it and it does work - although I was assuming the order of setting WhenCalled(s) doesn't really matter, but it definately does. If I do the WhenCalled after the Swap for instance, it doesn't work. It needs to go before the Swap. (Doesn't really make sense to me to be honest - it should be the same object).
However, the last example (one of the ways I had tried), doesn't work for me. I fake, set expecation on fake, and then set expectation on Singleton to return faked instance - but now it returns the concrete instance !
Could it have something to do with the way the constructors are called? I remember seeing something about that...
Alternatively I could use the Swap, but, I wanted to be able to setup all this stuff in a TestSetup, and make minor modifications to the expectations in the actual test, but that doesn't look possible. ?
The best solution is to not use singletons (or any other static mutable data). Just create one instance and use dependency injection to pass it to all objects who need it.
http://butunclebob.com/ArticleS.UncleBob.SingletonVsJustCreateOne
http://www.youtube.com/watch?v=-FRm3VPhseI