Issue
I have a service class that I need to unit test. The service has a upload method which in turn calls other services(autowired beans) that updates the database. I need to mock some of these services and some to execute as it is.
@Service
public class UploadServiceImpl implements UploadService{
@Autowired
private ServiceA serviceA;
@Autowired
private ServiceB serviceB;
public void upload(){
serviceA.execute();
serviceB.execute():
//code...
}
In the above example I need to mock ServiceA, but i would like ServiceB to run as is and perform it's function. My Junit test looks like this:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes=Swagger2SpringBoot.class)
public class UploadServiceTest {
@Mock
private ServiceA serviceA;
@InjectMocks
private UploadServiceImpl uploadService;
@Before
public void init() {
MockitoAnnotations.initMocks(this);
}
@Test
public void testUpload(){
uploadService.upload();
}
When I execute this I get NPE at serviceB.execute();
in UploadServiceImpl
.
What could be the problem?
Note: I am not specifying the behavior of the mocked object because I don't really care and also default behavior of mocked objects are to do nothing.
Thanks!
Solution
Usually when unit testing you want to mock all external dependencies of a class. That way the unit test can remain independent and focused on the class under test.
Nevertheless, if you want to mix Spring autowiring with Mockito mocks, an easy solution is to annotate with both @InjectMocks
and @Autowired
:
@InjectMocks
@Autowired
private UploadServiceImpl uploadService;
The net effect of this is that first Spring will autowire the bean, then Mockito will immediately overwrite the mocked dependencies with the available mocks.
Answered By - rustyx
Answer Checked By - Clifford M. (JavaFixing Volunteer)