Assume I have a base class:
class Command {
public:
virtual int8_t Execute();
};
with a definition in the base class cpp.
Additionally, I have a child class:
class SpecificCommand: public Command {
public:
int8_t Execute();
};
With the definition:
int8_t SpecificCommand::Execute() {
doSomeStuff();
Command::Execute();
}
How do I mock Command::Execute() but using a SpecificCommand object for tests?
Maybe something like that:
class SpecificCommandMock : public SpecificCommand
{
public:
MOCK_METHOD0(ExecuteMockedMethod, void());
int8_t Execute() override
{
doSomeStuff()
ExecuteMockedMethod();
}
}
Of course you should use SpecificCommandMock in unit tests and set EXPECT_CALL for ExecuteMockedMethod when class under test is expected to call Execute().
In addition I suppose that something could be wrong in design of the application if you have to do such things.
This should not be possible in the way you are expecting. I.e. gtest cannot just replace the part of your code and instead of:
int8_t SpecificCommand::Execute() {
doSomeStuff();
Command::Execute();
}
execute something like:
int8_t SpecificCommand::Execute() {
doSomeStuff();
}
You operate with macroses mainly which are just wrap your code with some other. So the language limitation still in there.
Some options (which don't affect your Command implementation):
if doSomeStuff is a public - override the Execute() with mock class as proposed by trivelt or do it like official docs suggests with ON_CALL declaration in mock constructor
write DummyCommand.cpp which do nothing and by compilation option build it instead of original one. In cmake it's if-else + add_library/add_executable manipulations.
write mock to the library which uses "network access that can not be tested" and link it instead of original one by compilation option. (if-else + target_link_library or even include manipulations in the cmake)
write mock for the network communication backend (web_server, etc)
Related
I'm looking for a way to make methods only available in Unit test scripts.
public class MyClass
{
public Data MyData { get; }
internal MyClass()
{
// Complex code setting MyData
}
#if UNITY_MACROS
public MyClass(MyData data)
{
MyData = data;
}
#endif
}
The need is that the public constructor would only be available in the Unit Test scripts and assembly.
I tried to look into Define constraints in the Test assembly but I am probably not using right since I don't see any difference.
What you need is to use the InternalsVisibleTo attribute (MS docs). You can add the following line either in your class source file, or in a separate AssemblyInfo.cs which you can create in the same folder as your asmdef file:
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("MyUnitTestAssembly")]
In that case you can leave MyClass(MyData data) internal.
I'm attempting to write Mocks for Private / Non Virtual / Static functions and come across a way to do the same.
Here is how it looks like..
Lets assume that I have a class A which needs to be mocked and used inside class UsingA. The definition of both classes looks like
class A
{
friend class UsingA;
int privateFn() {}
public:
int nonVirtual() {}
};
// The UsingA class
class UsingA {
A &a1;
public:
UsingA(A & _a1) : a1(_a1) {}
int CallFn() {
return a1.nonVirtual();
}
int CallFn2() {
return a1.privateFn();
}
};
I know that Mocks are meant for generating the behavior of the class and while creating Mocks, we need to derive from the original class.
However, to Mock the behavior I decided not to derive from the original class, instead comment the class A and generate a Mock class with the same Name i.e class A.
Here is how my mock class looks like
// Original class A is commented / header file removed
class A {
public:
MOCK_METHOD0(nonVirtual, int());
MOCK_METHOD0(privateFn, int());
};
And my tests are usual mock tests
TEST(MyMockTest, NonVirtualTest) {
A mstat;
UsingA ua(mstat);
EXPECT_CALL(mstat, nonVirtual())
.Times(1)
.WillOnce(Return(100));
int retVal = ua.CallFn();
EXPECT_EQ(retVal,100);
}
TEST(MyMockTest, PrivateTest) {
A mstat;
UsingA ua(mstat);
EXPECT_CALL(mstat, privateFn())
.Times(1)
.WillOnce(Return(100));
int retVal = ua.CallFn2();
EXPECT_EQ(retVal,100);
}
And everything works fine and I'm able to test UsingA by this mock.
Question is.
This looks easier and serves the purpose, still I haven't seen this kind of examples while browsing for google mock examples. Is there anything that would go wrong if I do this?
Honestly, I didn't find any.
NOTE: Folks, I'm using friend for demonstration only. My actual use case is totally different. Thanks
The wrong is that you are not testing real code, because of that:
comment the class A
generate a Mock class with the same name
These operations alter the code under test.
An example what can go wrong:
Change return type: long nonVirtual in Mock - previously was int
Test that on, let say, nonVirtual() == 0xFF'FFFF'FFFF (which is bigger than INTMAX) some action is being done
Forget to change in real A - so real UsingA have branch that is tested but never reachable in real code
An example code:
class A {
public:
MOCK_METHOD0(nonVirtual, long()); // change
MOCK_METHOD0(privateFn, int());
};
void UsingA::processA()
{
if (a.nonVirtual() > VERY_BIG_NUMBER)
{
throw runtime_error("oops");
}
}
TEST_F(UsingATest, throwOnVeryBigNumber)
{
EXPECT_CALL(aMock, nonVirtual()).WillOnce(Return(VERY_BIG_NUMBER + 1));
ASSERT_THROW(objectUndertTest.processA());
}
But real A did not change - so we test non reachable code in UsingA class:
class A {
public:
int nonVirtual(); // not changed
...
};
The best solution is (in order):
To test in isolation you have to isolate classes - so to use dependency injection (virtual functions etc, base interfaces, etc...) - this is sometimes called London School of TDD
Test both classes A and UsingA w/o any stubbing - test them together in one testcase - thus you test real code - this is called Detroit Shool of TDD
Separate by template code with good restriction on interface - this approach is most similar to yours:
Regarding 3 - you might use something like this:
template <class T = A>
class UsingA {
T &a1;
public:
UsingA(T & _a1) : a1(_a1) {}
long CallFn() {
using ANonVirtualResult = std::invoke_result_t<&T::nonVirtual>;
static_assert(std::is_same<long, ANonVirtualResult>::value);
return a1.nonVirtual();
}
...
};
And in test:
class UsingATest : public ::testing::Test
{
protected:
StrictMock<AMock> aMock;
using ClassUnderTest = UsingA<AMock>;
ClassUnderTest objectUnderTest{aMock};
};
TEST_F(UsingATest, useNonVirtual)
{
const auto VALUE = 123456;
EXPECT_CALL(aMock, nonVirtual()).WillOnce(Return(VALUE));
ASSERT_EQ(VALUE, objectUnderTest.CallFn());
}
You might note that some assumption about A might be tested during compilation as static_assert or via some SFINAE technics (more complicated).
Actually, there are examples with template code in googlemock as workaround for mocking classes w/o virtual functions.
We use your type of using mocks inside a few of our test projects to check callbacks on a larger class that we pass along using dependency injection. In our case, the methods are declared virtual.
In your case, they are not. Your mock implementation would hide the original implementation - if there was any. So I don't think there's an issue here.
This question is more like open discussion. I would like to start with an example. Suppose there is one service FooService
public interface IFooService { void Method1(){}}
public class FooService: IFooService { void Method1(){ ... }}
In order to test the service , we write the unit test code like below, no external services
public void TestMethod1(){ ... }
Then suppose in Method1 we need to use another class called AService which inherit from IAService
public interface IAService {void AMethod1(){}}
public class AService : IAService { void AMethod1() {}}
public class FooService : IFooService {
private IAService a;
public FooService (IAService a){ this.a = a;}
void Method1(){ a.AMethod1(); ..... business logic ..... }
}
Then we have to refactor the unit test to mock AService
public void TestMethod1(){
IMockAService aService = MockRepository.StrickMock<IAService>();
.....
}
So when need more external services, we have to add mock service, if some of services changed the logic or add or remove parameters, and so on. If there are 100 test cases, we have to modify all of test cases.
So what's the best solution for mocking increasing external services and effective way to handle any changes of external dependencies for example : add/remove parameters of methods.
thanks
Most times for me it's enough to create the class under test in a Setup method, leaving you with only one place to adapt when the constructor signature changes.
Alternatively you can move construction of the class under test to a private method.
Same goes for methods. Often you can wrap the call to a method under test in a private method. This is especially helpful, if you don't have to set up all passed parameters in every test, but can use defaults, which you might have prepared in your Setup method.
I am using PowerMock to mock static methods in junit tests, typically done as follows:
#RunWith(PowerMockRunner.class)
#PrepareForTest({Foo.class,Bar.class})
public class SomeUnitTest {
#Before
public void setUpTest() {
setUpFoo();
setUpBar();
}
private void setUpFoo() {
mockStatic(Foo.class);
when(Foo.someStaticMethod()).thenReturn(1);
}
private void setUpBar() {
mockStatic(Bar.class);
when(Bar.someStaticMethod()).thenReturn(2);
}
#Test
public void someTestCase() {
...
}
}
This works fine, but I'm finding that specifying the #PrepareForTest annotation is preventing me from making my testing API flexible.
What I'd like to do is something like the following:
public class MockLibraryOne {
public static void setUpLibraryOne() {
setUpFoo();
setUpBar();
}
private static void setUpFoo() {
mockStatic(Foo.class);
when(Foo.someStaticMethod()).thenReturn(1);
}
private static void setUpBar() {
mockStatic(Bar.class);
when(Bar.someStaticMethod()).thenReturn(2);
}
}
#RunWith(PowerMockRunner.class)
public class SomeUnitTest {
#Before
public void setUpTest() {
MockLibraryOne.setUpLibraryOne();
}
#Test
public void someTestCase() {
...
}
}
Here my unit test has a dependency on LibraryOne, but it does not know which classes LibraryOne depends on, so it does not know which classes to add to the #PrepareForTest annotation.
I could make SomeUnitTest extend MockLibraryOne and add the #PrepareForTest annotation to the MockLibraryOne class, but I will have dependencies on more than just MockLibraryOne in other unit tests, so inheritance is not a general solution.
Is there some way of programmatically preparing a class for testing under PowerMock, instead of using the #PrepareForTest annotation? For example, something like the following:
public class MockLibraryOne {
public static void setUpLibraryOne() {
setUpFoo();
setUpBar();
}
private static void setUpFoo() {
prepareForTest(Foo.class);
mockStatic(Foo.class);
when(Foo.someStaticMethod()).thenReturn(1);
}
private static void setUpBar() {
prepareForTest(Bar.class);
mockStatic(Bar.class);
when(Bar.someStaticMethod()).thenReturn(2);
}
}
I guess it would be nice if PowerMockRunner processed the #PrepareForTest annotation a little differently: for each specified class, it should not only add that class (and its hierarchy) to the list of classes to prepare for mocking, but then examine that class to see if it has any #PrepareForTest annotations as well:
#RunWith(PowerMockRunner.class)
#PrepareForTest({MockLibraryOne.class})
public class SomeUnitTest {
...
}
#PrepareForTest({Foo.class,Bar.class})
public class MockLibraryOne {
...
}
}
So in this the #PrepareForTest annotation on SomeUnitTest would find MockLibraryOne, and the #PrepareForTest annotation there would drag in Foo.class and Bar.class as well.
So perhaps writing my own test runner to replace PowerMockRunner may be a solution.
Or perhaps there's a simpler solution, using PowerMockAgent class, for example?
edit: Mock Policies may be one solution: https://code.google.com/p/powermock/wiki/MockPolicies
edit: Mock Policies works with PowerMockRunner but not (it seems) with PowerMockRule (which I sometimes require due to class loader issues).
What you try to achieve will not work.
The problem is that powermock must rewrite the client class's code to intercept the static invocation and it can't do this after the class is loaded. Thus it can only prepare a class for test before it is loaded.
Let's assume you want to mock the System.currentTimeMillis invocation in the following simple class.
class SystemClock {
public long getTime() {
return System.currentTimeMillis();
}
}
Powermock will not change the code of java.lang.System.currentTimeMillis, because it can't. Instead it changes the SystemClock's byte code so that it does not invoke System.currentTimeMillis anymore. Instead it invokes some other object that belong to powermock.
This is how powermock get's full control over the return value and allows you to write a test like this:
#RunWith(PowerMockRunner.class)
#PrepareForTest({ SystemClock.class })
public class PowerMockitoTest {
#Test
public void systemTimeMillis() {
SystemClock systemClock = new SystemClock();
PowerMockito.mockStatic(System.class);
PowerMockito.when(System.currentTimeMillis()).thenReturn(12345L);
long time = systemClock.getTime();
assertEquals(12345L, time);
}
}
You can see that powermock has rewritten the client class in the stacktrace of your debugger. Set a breakpoint at SystemClock.getTime and step into the invoked method.
As you can see SystemClock invokes a MockGateway.
If you take a look at the variables on the stack of the MockGateway invocation, you can see how the original System.currentTimeMillis method is handled.
Perhaps you're looking for a mock policy?
Could you help this (taken from documentation)?
You can also prepare whole packages for test by using wildcards:
#PrepareForTest(fullyQualifiedNames="com.mypackage.*")
So you can add the whole library to your prepare...
Why do you even want to mock static methods? Why not wrap those static methods in a class that you can mock with mockito?
class FooWraper {
void someMethod() {
Foo.someStaticMethod()
}
}
and then you can create a mock of your FooWraper. No need to use Powermock at all...
Here is my situation:
I want to test on the "HasSomething()" function, which is in the following class:
public class Something
{
private object _thing;
public virtual bool HasSomething()
{
if (HasSomething(_thing))
return true;
return false;
}
public virtual bool HasSomething(object thing)
{
....some algo here to check on the object...
return true;
}
}
So, i write my test to be like this:
public void HasSomethingTest1()
{
MockRepository mocks = new MockRepository();
Something target = mocks.DynamicMock(typeof(Something)) as Something;
Expect.Call(target.HasSomething(new Object())).IgnoreArguments().Return(true);
bool expected = true;
bool actual;
actual = target.HasSomething();
Assert.AreEqual(expected, actual);
}
Is my test written correctly?
Please help me as i can't even get the result as expected. the "HasSomething(object)" just can't be mock in that way. it did not return me 'true' as being set in expectation.
Thanks.
In response to OP's 'answer': Your main problem is that RhinoMocks does not mock members of classes - instead it creates mock classes and we can then set expectations and canned responses for its members (i.e. Properties and Functions). If you attempt to test a member function of a mock/stub class, you run the risk of testing the mocking framework rather than your implementation.
For the particular scenario of the logical path being dependent on the return value of a local (usually private) function, you really need an external dependency (another object) which would affect the return value that you require from that local function. For your code snippet above, I would write the test as follows:
[Test]
public void TestHasSomething()
{
// here I am assuming that _thing is being injected in via the constructor
// you could also do it via a property setter or a function
var sut = new Something(new object());
Assert.IsTrue(sut.HasSomething);
}
i.e. no mocking required.
This is one point of misunderstanding that I often had in the past with regards to mocking; we mock the behaviour of a dependency of the system under test (SUT). Something like: the SUT calls several methods of the dependency and the mocking process provides canned responses (rather than going to the database, etc) to guide the way the logic flows.
A simple example would be as follows (note that I have used RhinoMocks AAA syntax for this test. As an aside, I notice that the syntax that you are using in your code sample is using the Record-Replay paradigm, except that it isn't using Record and Replay! That would probably cause problems as well):
public class SUT
{
Dependency _depend
public SUT (Dependency depend)
{
_depend = depend;
}
...
public int MethodUnderTest()
{
if (_depend.IsReady)
return 1;
else
return -1;
}
}
...
[Test]
public void TestSUT_MethodUnderTest()
{
var dependency = MockRepository.GenerateMock<Dependency>();
dependency.Stub(d => d.IsReady).Return(true);
var sut = new SUT(dependency);
Assert.AreEqual(1, sut.MethodUnderTest());
}
And so the problem that you have is that you are attempting to test the behaviour of a mocked object. Which means that you aren't actually testing your class at all!
In a case like this, your test double should be a derived version of class Something. Then you override the method HasSomething(object) and ensure that HasSomething() calls your one.
If I understand correctly, you are actually interested in testing the method HasDynamicFlow (not depicted in your example above) without concerning yourself with the algorithm for HasSomething.
Preet is right in that you could simply subclass Something and override the behavior of HasSomething to short-circuit the algorithm, but that would require creating some additional test-dummy code which Rhino is efficient at eliminating.
Consider using a Partial Mock Stub instead of a Dynamic Mock. A stub is less strict and is ideal for working with Properties. Methods however require some extra effort.
[Test]
public void CanStubMethod()
{
Foo foo = MockRepository.GenerateStub<Foo>();
foo.Expect(f => f.HasDynamicFlow()).CallOriginalMethod(OriginalCallOptions.NoExpectation);
foo.Expect(f => f.HasSomething()).CallOriginalMethod(OriginalCallOptions.NoExpectation);
foo.Expect(f => f.HasSomething(null)).IgnoreArguments().Return(true);
Assert.IsTrue(foo.HasDynamicFlow());
}
EDIT: added code example and switched Partial Mock to Stub