4

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

asked Mar 20, 2019 at 9:09

2 Answers 2

2

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

answered Feb 20, 2021 at 11:41
Sign up to request clarification or add additional context in comments.

Comments

0

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");
 }
}
answered Mar 20, 2019 at 9:20

3 Comments

Thank you for the share. I did exactly as you wrote but the object is still null. It's look that the problem might be causes from something else - Spring or something else.
Are you still using @MockBean(name="mockWS")? I don't think that you need to give the name of the bean. Also maybe you have to check the position of @SpringBootApplication annotation, maybe you have an issue with the component scan.
I removed the name from @MockBean @MockBean IMockWS mockService;. Regarding @SpringBootApplication, it locates in the root of package

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.