I am new to Google Test.
I have one base class and derived class with calling class
class Base
{
public:
virtual ~Base() {}
virtual int target_method() = 0;
}
class DerivedClass : public Base
{
public:
virtual ~DerivedClass () {}
int target_method() override;
}
class CallingClass
{
public:
CallingClass(std::unique_ptr<DerivedClass> _drivedClass);
private:
std::unique_ptr<DerivedClass> drivedClass;
}
From my Test:
class MockDerivedClass : public DerivedClass
{
public:
MOCK_METHOD0(target_method, int());
}
TEST(TestGroup, Test1)
{
std::unique_ptr<MockDerivedClass> mockClass(new MockDerivedClass());
EXPECT_CALL(*mockClass, target_method()).WillRepeatedly(Return(1));
CallingClass callingClass(std::move(mockClass));
callingClass.callSomthing();
EXPECT_EQ(_ , _);
}
The test is running fine and the mock method is being called as expected. At the end of test I am getting this error:
ERROR: this mock object (used in test TestGroup.Test1) should be deleted but never is. Its address is #0x5585d93e4770.
ERROR: 1 leaked mock object found at program exit. Expectations on a mock object is verified when the object is destructed. Leaking a mock means that its expectations aren't verified, which is usually a test bug. If you really intend to leak a mock, you can suppress this error using testing::Mock::AllowLeak(mock_object), or you may use a fake or stub instead of a mock.
Is there anything can be done at end of test to suppress this or to resolve this?
By using a uniqe_ptr, the owner of the mock object becomes the CallingClass. The leak detection expects mockClass to be destructed within your TEST, not possibly after that.
Note that gMock will verify the expectations on a mock object when it is destructed. See this reference.
You can either avoid using a unique pointer and construct the mock object in your test and just pass its address to your CallingClass, or add this at the end of your test:
EXPECT_TRUE(Mock::VerifyAndClearExpectations(mockClass.get()));
This verifies and removes the expectations on mockClass and returns true if and only if successful.
Related
Consider the code given below:
#Override
public void A() {
objectA = objectB.B();
objectA.C(someValue);
objectC = new constructor(objectA,callback());
//Rest of the code
}
}
public Callback callback() {
return new callback() {
#Override
public void someMethod(someArgument) {
//some Code
}
};
}
I am trying to write a unit test case where:
the call objectB.B() has to be mocked
the call to the constructor has to be mocked
This is what I have done using Mockito and Powermockito:
#InjectMocks
ClassBeingTested testObject;
#Mock
ClassB objectB;
#Mock
ClassC objectC;
#Before()
public void setup() {
when(objectB.B()).thenReturn(new ObjectA("someValue"));
whenNew(objectC.class).withArguments(any(),any()).thenReturn(objectC);
}
#Test()
public void testMethod() {
testObject.A();
}
The first mock successfully works but the second mock using whenNew fails with the following error:
org.powermock.reflect.exceptions.ConstructorNotFoundException: No constructor found in class 'ClassC' with parameter types: [ null ]
If I use withArguments(objectA, callback()) where I have the implementation of callback in my test class, the actual constructor is called.
I want to mock the constructor call and restrict the call to the actual constructor. How can I do that?
I can not edit the code design since that is out of my scope.
In short, you get the error due to usage of 2 generic any() matchers.
When you use .withArguments(...) and set both as any() it implies
.withArguments(null, null) (since any() may match pretty much anything including nulls) which folds eventually as a single null and reflection api (which PowerMock heavily relies on) fails to discover a suitable constructor for ClassC(null).
You may check out the source of org.powermock.api.mockito.internal.expectation.AbstractConstructorExpectationSetup<T>
source that does the job
To fix up the issue consider using either .withAnyArguments() if you do not care of param types and stubbing all available constructors OR specify more concrete types while using any() like so
whenNew(ClassC.class).withArguments(any(ClassA.class), any(Callback.class))
I have a singleton class "Fake"
public class Fake{
private static Fake instance;
private Fake(){
}
public static Fake getInstance(){
if(instance == null)
instance = new Fake();
return instance;
}
public String getTestString(String s){
return s;
}
}
I want to create a mock Fake object so I can mock method calls to non-static method getTestString(String s). I have used both Mockito and PowerMock (Mockito extension) in the way that comes below.
//using Mockito
Fake fake = Mockito.mock(Fake.class);
//using PowerMock
Fake fake = mock(Fake.class);
In both cases, as the code is attempting to mock a singleton (with a private constructor) I expect an exception to occur, but it just normally works. I suspect that there is something wrong with it and maybe it is not working actually.
Mocking doesn't instantiate a class, it creates a proxy for it. Having a private constructor or a constructor with parameters doesn't make a difference.
The behavior you're seeing is normal and expected.
By using mocking, it means you are not testing the class itself, but want to dictate the behavior of the class so that it performs in an arbitrary way you want.
The mock is only useful when you are trying to test some other class which has a dependency on the class being mocked.
In your case, if you want to test the class being a Singleton, you should test on an REAL instance rather than a mock of the class.
Moreover, your method:
public String getTestString(String s){
return s;
}
always returns the String you passed in, this does not look right to me and not sure what you are trying to do here.
Because you're not ever creating an actual instance of Fake, only an instance of a proxy that fulfills Fake's interface, the mock is succeeding.
Separately, regardless of whether Fake's constructor is private, Mockito cannot stub or verify static methods. If your real goal is to override getInstance, you'll need to do so with PowerMock.
However, by adjusting your system-under-test, you can skip Powermock and test your method with Mockito directly:
public class YourSystemUnderTest {
public int yourMethodUnderTest() {
return yourMethodUnderTest(Fake.getInstance());
}
/** Visible for testing. */
int yourMethodUnderTest(Fake fake) {
// ...
}
}
public class YourTest {
#Test
public void yourMethodShouldReturn42() {
Fake fake = mock(Fake.class);
YourSystemUnderTest systemUnderTest = new YourSystemUnderTest();
assertEquals(42, systemUnderTest.yourMethodUnderTest(fake));
}
}
It's even easier if YourSystemUnderTest takes a Fake instance in its constructor, because then you can set up the reference to the Fake instance once in a setUp() or #Before method.
I have a class which carries a couple of dependencies which I'd like to mock using Google Mocks, in order to test the class with Google Test.
Simplified, I have the following1:
template<typename TDep>
class SUT {
private:
TDep dependency;
public:
explicit SUT(const TDep& dep) : dependency(dep) { }
SUT(const SUT& other) : dependency(dep.other) { }
// some methods that use the dependency
}
I also have an interface for the dependency,
class IDependency {
public:
virtual double calculateCoolStuff(double) const = 0;
virtual ~IDependency() { };
}
and a mock object
class MockDependency {
public:
MOCK_CONST_METHOD1(calculateCoolStuff, double(double));
};
However, when I try to compile something like
MockDependency mock;
SUT sut(mock);
I get errors stating error: use of deleted function MockDependency(const MockDependency&), i.e. there is no copy-constructor of the mocked object. I found this discussion on Google Groups which basically ends in making mock objects non-copyable, but allowing the user to add a copy constructor and define copy behavior manually. Very well:
class MockDependency {
public:
MockDependency(const MockDependency& other) { }
MOCK_CONST_METHOD1(calculateCoolStuff, double(double));
};
Now my code compiles, but if I run something like
MockDependency mock;
SUT sut(mock);
EXPECT_CALL(mock, calculateCoolStuff(2.0)).WillRepeatedly(Return(3.0));
sut.doStuff(); // Calls calculateCoolStuff
in a test, I get an error stating that the call was never set up. In other words, the instance mock which I can use to setup expectations, is no longer the same as the instance on SUT used for calculations. This makes testing with GMock and DI difficult, to say the least...
What is the best solution to this?
1) Yes, I'm using poor man's DI. Not the topic of this conversation...
You can use dependency injection with references by ensuring that your class member is a reference:
template<typename TDep>
class SUT {
private:
TDep& dependency; // Reference
// etc.
}
Note that you no longer need a copy constructor on MockDependency. As a rule, you need access to all instances of mock objects being used by your SUT to set up expectations on them.
I use GoogleMock/GoogleTest for testing, and I'm seeing some strange behavior when a matcher has a shared_ptr to a mock as a parameter, and EXPECT is called on the same shared_ptr. The offending piece of code:
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
using namespace boost;
using namespace testing;
struct MyParameter
{
virtual ~MyParameter() {}
virtual void myMethod() = 0;
};
struct MyParameterMock : public MyParameter
{
MOCK_METHOD0(myMethod, void());
};
struct MyClass
{
virtual ~MyClass() {}
virtual void myMethod(shared_ptr<MyParameter> p) {}
};
struct MyClassMock : public MyClass
{
MOCK_METHOD1(myMethod, void(shared_ptr<MyParameter>));
};
TEST(LeakTest, GoogleMockLeaksMatchedPointer)
{
shared_ptr<MyClassMock> c = make_shared<MyClassMock>();
shared_ptr<MyParameterMock> p = make_shared<MyParameterMock>();
{
InSequence dummy;
EXPECT_CALL(*c, myMethod(Eq(p)));
EXPECT_CALL(*p, myMethod());
}
c->myMethod(p);
p->myMethod();
}
When this test is run, I get
leak_ptr_mock.cpp:37: ERROR: this mock object (used in test LeakTest.GoogleMockLeaksMatchedPointer) should be deleted but never is. Its address is #0x9309544.
ERROR: 1 leaked mock object found at program exit.
Any idea of why this happens? I rather not have to use Mock::AllowLeak.
This is a result of holding p as a shared_ptr, using InSequence and the order in which you have declared your expectations.
When you call
EXPECT_CALL(*c, myMethod(Eq(p)));
you increase the use_count of p. In order for the leak detection to pass, p must be destroyed at (or before) the end of TEST.
The problem here is that internally, gmock maintains a record of the required mock call sequence by holding a pointer to the preceding expectation. So when you call EXPECT_CALL(*p, myMethod());, it gets a copy of the pointer to the previous expectation.
This then has the effect of blocking the call to p's destructor when TEST ends.
In order to work around this, I think your best bet is to call
EXPECT_TRUE(Mock::VerifyAndClearExpectations(p.get()));
just before you exit TEST. This clears the expectations on p, including critically its prerequisite expectation, which in turn allows the destructor of p to be invoked correctly.
Alternatively, if the order of the mock calls is unimportant, simply removing InSequence dummy; will also allow p's destructor to execute.
As an aside, your code has a couple of issues;
Your base structs should have virtual destructors
MyClass::myMethod should be virtual in order to allow gmock's function to override it
p->myMethod(p); should be p->myMethod();
Using GMock, how can I verify that a class's destructor is called? Is there a way, other than to wrap it in another class?
The obvious method, EXPECT_CALL(object, ~classtype()) yields a compiler error (gmock cannot produce a mock method called gmock_~classtype).
An easy way to check for a destructor call:
class MockFoo : public Foo {
...
// Add the following two lines to the mock class.
MOCK_METHOD0(Die, void());
virtual ~MockFoo() { Die(); }
};
In your test function:
MockFoo* foo = new MockFoo;
...
{
EXPECT_CALL(*foo, Die());
}
More Details can be found here:
Mocking Destructors
Unless you're passing --gmock_catch_leaked_mocks=0, then gmock should already be detecting when you fail to destroy a mock. The destructor is where unsatisfied expectations are flagged as errors, so gmock has special support for detecting when it is not called.