Mockito mocking method with this parameter - java

I have scenario when I want mock a method with this parameter, my method looks like below
this.listener = myCustomFactory.buildCustomListener(this);
I have mocked instance of myCustomFactory as given below
#Mock
MyCustomFactory myCustomFactory;
Is it possible to mock method with this parameter. 'this' refer the class for which I am writing unit test, I am creating reference for that class
Mockito.when(this.myCustomFactory.buildCustomListener(this.myClassObjectToBeTested).thenReturn(this.mockedListener);

Using Mockito.any(Class<T> clazz) solved the issue
Mockito.when(this.myCustomFactory.buildCustomListener(Mockito.any(MyClassToBeTested.class)).thenReturn(this.mockedListener);

Related

How to inject mock collection by annotation with Mockito

I have create one parameterized class that takes two params. One is type of string and another is type of List of Abstract class. Class constructor looks like below code.
public TestService(Tenant tenant, List<AbstractService> testServices) {
testServicesMap = testServices.stream().collect(Collectors.toMap(AbstractService::getType, Function.identity()));
}
now I want to write Junit test case for this class and for that I have following piece of code.
#Mock
protected Tenant tenant;
#Mock
private List<AbstractService> testServices;
#InjectMocks
private TestService testService;
#Before
public void setup() {
testServices.add(new JobService(new JobEventService()));
testServices.add(new ApplicationService(new ApplicationEventService()));
testServices.add(new UserService(new UserEventService()));
// notificationService = new NotificationService(tenant, notificationServices);
// MockitoAnnotations.initMocks(notificationService);
}
I also tried to enabled two commented lines but its now working. Following is error that system throw on start.
org.mockito.exceptions.base.MockitoException:
Cannot instantiate #InjectMocks field named 'notificationService' of type 'class com.test.TestService'.
You haven't provided the instance at field declaration so I tried to construct the instance.
However the constructor or the initialization block threw an exception : `null`.
Could someone help on this ?
you are mixing mocks with real objects, because you create a mock of list but then call add method on that list and then you expect stream() to work as usually.
Mockito mocks don't do anything by default so you have to tell it:
Mockito.when(testServices.stream())
.thenReturn(Stream.of(new JobService(new JobEventService())));
or better in your case is to remove #Mock from testServices and assign it a new ArrayList
The problem is that you try to mock the list, and list.stream() is called, which in the mock default returns null.
A common solution from the duplicate questions is to use a #Spy of the list.

capture parameters passes to stub in powermockito

How can I capture (for assertion purposes) the parmeters passed to a static stub method call?
The methodBeingStubbed looks like this...
public class SomeStaticClass{
protected static String methodBeingStubbed(Properties props){
...
I am stubbing the method call because it i need to verify that it gets called...
PowerMockito.stub(PowerMockito.method(SomeStaticClass.class, "methodBeingStubbed")).toReturn(null);
PowerMockito.verifyStatic();
But I now also want to know what properties were passed to this "methodBeingStubbed" and assert it is as expected
After the call to verifyStatic, you'll need to actually call the method you're trying to verify, as in the documentation here:
PowerMockito.verifyStatic(Static.class);
Static.thirdStaticMethod(Mockito.anyInt());
At that point you can use Mockito argument captors, as demonstrated (but not tested):
ArgumentCaptor<Properties> propertiesCaptor =
ArgumentCaptor.forClass(Properties.class);
PowerMockito.verifyStatic(SomeStaticClass.class);
SomeStaticClass.methodBeingStubbed(propertiesCaptor.capture());
Properties passedInValue = propertiesCaptor.getValue();
If you're used to #Mock annotations, or you need to capture a generic (as in List<String>), you may also be interested in using the #Captor annotation instead.

Need advice on unit testing with suppressing submethods and constructors

I have some weird code like this
B param = ...;
D main(){
return A.method(param, C.class, new String[]{"abc"}, new SomeClass()).get();
}
where
public static A method(...)
public D get()
How can I mock method main() to suppress submethods invocations and suppress constructing of objects?
I need to mock result of get()
Aside from a better designed method that injects instances into the method instead of create them, you can use Powermock to mock constructor calls so the calls to new will actually create mock objects.
here is powermock's tutorial on mock constructors with mockitto
http://code.google.com/p/powermock/wiki/MockitoUsage13
IN your test you will be able to say:
SomeClass myMock = mock(SomeClass.class);
whenNew(SomeClass.class).withNoArguments().thenReturn(myMock)

Mocking a Private Variable that is Assumed to Exist

How can you get a mock object in at runtime when it is not created/initialized in the class you are testing, it is not static (singleton pattern), or you don't have some sort of test constructor to hook into?
In a class that I am writing some unit testing for, I have come across a scenario I haven't encountered/solved yet. I have a JMS resource (a QueueConnectionFactory for reference, but it shouldn't matter), that is a private variable of the class I am testing. Since it has the javax.annotation.Resource annotation, at runtime it is assumed to be available. During testing, it is not, which creates the need for mocking this object.
It is not a static class and is not being used in a static way, if it was I could easily mock using the various static mocking methods I have run into. Since the resource is never created locally (in a constructor or even in a test constructor), I have no way of passing in a Mock object so that at runtime of the test, the mock is used instead of the actual object. How can I mock this Resource so that when the test executes, it will be used in place of the private #Resource object in the class I am testing?
For reference, the code is calling createConnection() on the QueueConnectionFactory which is throwing a null pointer exception since the Factory has not been initialized/mocked.
#Stateless
public class Example{
#Resource(name = "jms/exampleQCF")
private QueueConnectionFactory queueFactory;
...
public void testMe(){
Connection connection = queueFactory.createConnection();
...
}
}
After a lot more hunting around and looking at all the options Mockito/Powermock had to offer, I found the solution (which I will share in case others run into this same issue).
When you have private member variables that are never initialized (and just assumed created in other places), you can use the #InjectMocks annotation to "inject" Mocks you want into your class you are testing.
Add a variable in your test class for the class you are testing, and give it the annotation #InjectMocks (org.Mockito.InjectMocks).
Use #Mock annotations to setup the mocks you want to inject. Use the #Mock (name = "privateVariableNameHere") name property to map the Mock object to the private variable inside your class you are testing.
In either a setup function or before you call your class, initialize the mocks. The easiest way I have found is to use a "setup" method with the #Before annotation. Then inside there call MockitoAnnotations.initMocks(this); to quickly initialize anything with the #Mock annotation.
Define your Mock functionality in your test method (before calling the method you are testing).
Using the #InjectMock object, call your method you are testing... the mocks SHOULD be hooked in and working as defined in the earlier steps.
So for the example class I use above, the code to test/mock would have Connection returned as a mock which you can do whatever with. Based on the example above in my question, this is what the code would look like:
#RunWith(PowerMockRunner.class)
#PrepareForTest({/* Static Classes I am Mocking */})
public class ExampleTest {
#Mock (name = "queueFactory") //same name as private var.
QueueConnectionFactory queueFactoryMock;
#Mock
Connection connectionMock; //the object we want returned
#InjectMocks
Example exampleTester; //the class to test
#Before
public void setup(){
MockitoAnnotations.initMocks(this); // initialize all the #Mock objects
// Setup other Static Mocks
}
#Test
public void testTestMe(){
//Mock your objects like other "normally" mocked objects
PowerMockito.when(queueFactoryMock.createConnection()).thenReturn(connectionMock);
//...Mock ConnectionMock functionality...
exampleTester.testMe();
}
}
Several approaches here:
ReflectionTestUtils of Spring Testing framework: ReflectionTestUtils.setField(objectToTest, "privateFieldName", mockObjectToInject);. With this you don't introduce another dependency.
org.mockito.internal.util.reflection.FieldSetter.
PowerMock.Whitebox.setInternalState() to mock a private field.
If you need to mock internal local variable creation, use PowerMockito.whenNew(Foo.class).withNoArguments().thenReturn(foo);. Very, very useful. Cannot find other ways to do the same.
With only Mockito you cannot mock local variable creation, because when(any(Foo.class) does not work; will return null. It compiles but does not work.
References:
Mockito: Mock private field initialization

Powermock not returning correct object static method

I am using PowerMock to try and mock a final class with static methods, but whenever my code calls MyClass.getInstance() it returns null
In my tests I have annotated the test class
#RunWith(PowerMockRunner.class)
#PrepareForTest(MyClass.class)
In my method to make the mock I do the following
suppressConstructor(MyClass.class);
PowerMock.mockStatic(MyClass.class);
mockClass = PowerMock.createMock(MyClass.class);
expect(MyClass.getInstance()).andReturn(mockClass);
Should PowerMock.createMock create an EasyMock class?
When I call this in my code (MyClass.getInstance()), it always returns null but if I step through the test class the variable mockClass gets instantiated.
It seems like you using the EasyMock way of mocking. Have you replayed the MyClass before calling the getInstance() method, e.g.
PowerMock.replay(MyClass.class);
?
From the PowerMock MockStatic documentation:
Use PowerMock.mockStatic(ClassThatContainsStaticMethod.class) to mock all methods of this class.
Use PowerMock.replay(ClassThatContainsStaticMethod.class) to change the class to replay mode.
Use PowerMock.verify(ClassThatContainsStaticMethod.class) to change the class to verify mode.

Categories

Resources