Mocking a parameterized constructor using powermockito - unit-testing

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))

Related

Ignore method calls inside constructor for testing constructor method with Mockito and Junit4

how are you?
I'm trying to implement an unitary test for a class constructor. I can't modify the code of the class i'm testing.
The scenario i'm dealing with looks like this:
The class
public ClassIWantToTest{
//Class constructor
public void ClassIWantToTest(){
...
methodA();
...
methodB();
...
}
public void methodA(){
//do something...
}
public void methodB(){
//do something...
}
}
The test
#Test
public void testForConstructor(){
Atribute1 atb1 = mock(...);
Atribute2 atb2 = mock(...);
ClassIWantToTest c = new ClassIWantToTest();
doNothing().when(c).methodA();
doNothing().when(c).methodB();
assertEquals("atb1",atb1);
assertEquals("atb2",atb2);
...
}
methodA() and methodB() are void. I want to ignore them and just check if the atributes got correctly inserted in the class object instance I've created. I can't figure out how to do this since methodA and methodB are called in the constructor and I cant test the constructor without calling it. I also can't call "doNothing()" for methodA() and methodB() since an ClassIWantToTest mock needs to be created for the "doNothing()" call.
I tried to create a ClassIWantToTest mock and use "doCallRealMethod()" for the constructor test, but I cant call the constructor method for mocked object instances.
I would be grateful if someone could help me.
I tried to create a ClassIWantToTest mock and use "doCallRealMethod()" for the constructor call(since I want to test this call) and use "doNothing()" for the methodA() and methodB() calls, but I cant call the constructor method for mocked object instances. Doing this I wanted to call the constructor method and ignore the methodA() and methodB() with the doNothing().

Google mock with unique_ptr object giving memory leak issue

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.

How to mock a method of the same class?

In the testing method, there are methods of the same class. How to mock the methods of the same class?
An example is as follows.
I am testing method2. It involves method1 which is in the same class. How to mock this method1?
public class A
{
public void method1(int a, int b){
}
public void method2(){
int value = method1(10,20);
}
}
You can use a Spy to do this, in combination with doReturn to stub out the method for which you want to provide canned behavior. There are many examples available on how to use a spy. Check out these tutorials and documentation:
Mockito: mocking a method of same class called by method under test when using #InjectMocks
https://www.baeldung.com/mockito-spy
Mockito: Trying to spy on method is calling the original method
Example:
List list = new LinkedList();
List spy = spy(list);
//Use doReturn to change the behavior of a method call
doReturn("foo").when(spy).get(0);

Why it doesn't throw any exceptions when attempting to mock a singleton using either Mockito or PowerMock?

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.

How do I use GMock with dependency injection?

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.