Reputation: 1176
I have Spring Integration test where I'm trying to Mock some of my Beans. For some reason although I Mocked them they are NULL. Here is code snippet:
The Bean which I want to Mock
@Component
public class MockWS {
public String callSoapClient() throws JAXBException{
return "CallSoapCl";
}
}
The class where the Bean is used
public class SmDpES2PortImpl implements ES2SmDp {
@Autowired
private MockWS mock;
@Override
public void es2DownloadProfile(ES2DownloadProfileRequest parameters) {
try {
LOG.info("\n\n\n TEST BEAN: " + mock.callSoapClient() + "\n\n");
}
}
}
Spring boot integration test where the Bean has been mocked
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class ES2SmDpApplicationTests {
@MockBean(name="mockWS")
MockWS mockService;
@Test
public void test1Es2DownloadProfile_Sucess() throws MalformedURLException, JAXBException, SOAPException {
when(mockService.callSoapClient()).thenReturn("CallMockCLient");
}
}
Output from the build execution: TEST BEAN: null
Upvotes: 4
Views: 12384
Reputation: 1562
In my case the following combination of annotations worked:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = { ControllerThatIAmTesting.class })
@AutoConfigureMockMvc(addFilters = false) // if using MockMvc object
But I had to declare explicitly both Autowired objects that I use in the ControllerThatIAmTesting in the test class with @MockBean annotation - otherwise Spring would complain that it cannot find suitable implementation - incidentally both my interfaces and their implementations are in the same corresponding packages
Also, using @WebMvcTest instead of @SpringBootTest (other suggest it as more specific scenario) resulted in Spring failing to find and initialize some other @Autowired dependencies from my @Configuration classes.
Related posts post1 post2 post3
Upvotes: 2
Reputation: 3393
You should mock an interface, not a class. Also, SmDpES2PortImpl
must be a Spring bean. Try the following:
Interface:
public interface IMockWS {
public String callSoapClient() throws JAXBException;
}
Component class:
@Component
public class MockWS implements IMockWS {
@Override
public String callSoapClient() throws JAXBException{
return "CallSoapCl";
}
}
Service class:
@Service //Also @Component is a good alternative
public class SmDpES2PortImpl implements ES2SmDp {
@Autowired
private IMockWS mock; //Notice that you are wiring an interface
@Override
public void es2DownloadProfile(ES2DownloadProfileRequest parameters) {
try {
LOG.info("\n\n\n TEST BEAN: " + mock.callSoapClient() + "\n\n");
}
}
}
Test class:
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class ES2SmDpApplicationTests {
@MockBean
IMockWS mockService; //Again, you are mocking the interface, not the implementing class
@Test
public void test1Es2DownloadProfile_Sucess() throws MalformedURLException, JAXBException, SOAPException {
when(mockService.callSoapClient()).thenReturn("CallMockCLient");
}
}
Upvotes: 0