I am writing unit tests for the following class
Class to Be Tested:
public class RandomManager {
@Autowired
private ApplicationContext context;
@Autowired
private ClassA objectA;
public void methodToBeTested() {
objectA.methodToBeVerified(context.getBean(Random.class,"Yaswanth","Yaswanth"));
}
}
Below is the test class:
public class RandomManagerTest {
@Mock
private ClassA objectA;
@Mock
private ApplicationContext context;
@InjectMocks
private RandomManager randomManager;
@BeforeTest
public void before() {
MockitoAnnotations.initMocks(this);
doReturn(any(Random.class)).when(context)
.getBean(any(Class.class), any(), any());
}
@Test
public void methodToBeTestedTest() {
Random randomObject = new RandomObject("Yaswanth", "Yaswanth");
randomManager.methodToBeTested();
verify(objectA).methodToBeVerified(randomObject);
}
}
The above code fails in the before method when I am trying to stub the applicationContext mock. I get the following error.
You cannot use argument matchers outside of verification or stubbing. Examples of correct usage of argument matchers: when(mock.get(anyInt())).thenReturn(null); doThrow(new RuntimeException()).when(mock).someVoidMethod(anyObject()); verify(mock).someMethod(contains("foo"))
This message may appear after an NullPointerException if the last matcher is returning an object like any() but the stubbed method signature expect a primitive argument, in this case, use primitive alternatives. when(mock.get(any())); // bad use, will raise NPE when(mock.get(anyInt())); // correct usage use
Also, this error might show up because you use argument matchers with methods that cannot be mocked. Following methods cannot be stubbed/verified: final/private/equals()/hashCode(). Mocking methods declared on non-public parent classes is not supported.
Can anyone please help me understand what am I doing wrong in the above code?
Note: I am using TestNG and Mockito. I can extend
AbstractTestNGSpringContextTests
and use a spring-test.xml
, declare my
beans and autowire applicationContext. I feel that is an overkill for
my use case. I need to just mock applicationContext's getBean method.
@RunWith(SpringJUnit4ClassRunner.class)
you can load all you spring beans, and they will be wired together, and you test the actual code, rather than stubs that return something defined in the test, and never actually execute the code inside dependent beans. Mocking is a great tool when used right, but I have never used it for Spring based test, and when I have seen others do it, it has always been a mess. – Klaus Groenbaek@RunWith
is not available with TestNG andAbstractTestNGSpringContextTests
should be used instead. – juherr