Reputation: 549
Hi I am trying to do some unit tests with async methods. below is my code. the first line of methodUnderTest() where I mocked the doWork is returning null during execution and test fails. I tried different things related to async but nothing worked. What am I missing here.
public class AServiceImpl{
@Autowired
BService bService;
@Async
public CompletableFuture<String> methodUnderTest(String input){
String s = bService.doWork(input.substring(3));
//blah blah blah
return CompletableFuture.completedFuture(s);
}
}
public class AServiceTest{
private BService bService;
private AService aService;
@Before
void beforeTest(){
aService = new AServiceImpl();
bService = mock(BService.class);
//blah blah blah
}
@Test
public void someUnitTest(){
Mockito.when(bService.doWork(any())).thenReturn("ABC");
String s = aService.methodUnderTest("ABCDEF").get();
Assert.assertNotNull(s);
}
}
Upvotes: 2
Views: 956
Reputation: 945
Your auto wiring will only work in the production code. You need to manually inject your mock BService
in your test.
@Before
void beforeTest() {
aService = new AServiceImpl();
bService = mock(BService.class);
aService.bService = bService;
...
}
You may be able to run your tests with spring to inject test dependencies using @RunWith(SpringRunner.class)
(JUnit 4) or @ExtendWith(SpringExtension.class)
(Junit 5).
Upvotes: 0
Reputation: 247153
Nothing to do with @Async
here. The mock setup in the test is not being assigned to the subject under test.
First I would suggest avoiding Autowired fields and having your class explicitly expose their dependencies via constructor dependencies
public class AServiceImpl {
private final BService bService;
@Autowired
public AServiceImpl(BService bService) {
this.bService = bService;
}
@Async
public CompletableFuture<String> methodUnderTest(String input) {
String s = bService.doWork(input.substring(3));
//...
return CompletableFuture.completedFuture(s);
}
}
And then explicitly inject the dependency when testing
public class AServiceTest{
private BService bService;
private AService aService;
@Before
void beforeTest() {
bService = mock(BService.class);
aService = new AServiceImpl(bService); //<-- injecting mocked dependency
//...
}
@Test
public void someUnitTest(){
// Arrange
Mockito.when(bService.doWork(any())).thenReturn("ABC");
// Act
String s = aService.methodUnderTest("ABCDEF").get();
// Assert
Assert.assertNotNull(s);
}
}
Upvotes: 1