I have an XYZ class which is autowired in ABC and in class MyClass I have a method name doSomething() inside that method I do ABC abc = new ABC(); Then I call abc.someMethod();
Please see code sample below :
Class ABC
public class ABC {
@Autowire
private XYZ xyz;
public void someMethod()
{
//Some stuff
xyz.someFunc();
}
}
Class MyCLass
public class MyCLass {
public void doSomething() {
ABC abc = new ABC();
abc.someMethod();
}
}
Need unit test doSomething() but I NPE as XYZ is null in ABC. How can I mock @Autowire in this case.
CodePudding user response:
If you use constructor injection instead of field injection, you can create the mock and give it to the constructor of ABC:
public class ABC {
private final XYZ xyz;
public ABC(XYZ xyz) {
this.xyz = xyz;
}
public void someMethod()
{
//Some stuff
xyz.someFunc();
}
}
Then in your test, when you create the instance under test, you just create it and hand over the mock:
XYZ mock = mock(XYZ.class);
ABC underTest = new ABC(mock);
CodePudding user response:
You can use the following testing capabilities in your test:
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
Provide a configuration and use it, for example:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = MyTest.MyTestConfiguration.class)
public class MyTest {
// xyz injected into ABC and MyTest for convenience.
@Autowired
private XYZ xyz;
@Test
public void myTest() {
// Some Stubbing...
when(xyz.trySomething()).thenReturn(true);
// Some verification.
new ABC().doSomething();
verify(xyz, times(1))
.trySomething();
}
// Note it is used in @ContextConfiguration
@Configuration
static class MyTestConfiguration {
@Bean
XYZ xyz() {
return mock(XYZ.class);
}
}
}
The documentation is a bit extensive, search for the mentioned annotations here https://docs.spring.io/spring-framework/docs/current/reference/html/testing.html#integration-testing