I have this REST controller:
package com.company.rest;
@RestController
@RequestMapping("/v1/orders")
public class OrderController {
@Autowired
private OrderService orderService;
...
being the OrderService
implementation:
package com.company.service.impl;
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private MessageService messageService;
...
and MessageService
implementation:
package com.company.service.impl;
import org.springframework.mail.javamail.JavaMailSender;
@Service
public class MessageServiceImpl implements MessageService {
@Autowired
public JavaMailSender emailSender;
...
This works perfect in development environment, but I have this unit test for the OrderController
(based on this tutorial):
package com.company.test;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = AdminApplication.class)
@WebAppConfiguration
public class OrderTest {
private MockMvc mockMvc;
@Autowired
private OrderService orderService;
...
which results in:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.mail.javamail.JavaMailSender' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
Why does this dependency is satisfied in production but not in test? What do I need to do to allow this unit test successfully inject (or mock) a JavaMailSender
implementation?
The JavaMailSender
bean is not created beacause Spring test runner cannot get required configuration.
For example, there is no spring.mail.host
in application.properties
.
One of the solution is adding a TestConfiguration
for JavaMailSender
.
@TestConfiguration
public class TestConfigForMail {
@Bean
public JavaMailSender mailSender() {
final JavaMailSenderImpl sender = new MockMailSender();
return sender;
}
private class MockMailSender extends JavaMailSenderImpl {
@Override
public void send(final MimeMessagePreparator mimeMessagePreparator) throws MailException {
final MimeMessage mimeMessage = createMimeMessage();
try {
mimeMessagePreparator.prepare(mimeMessage);
final String content = (String) mimeMessage.getContent();
final Properties javaMailProperties = getJavaMailProperties();
javaMailProperties.setProperty("mailContent", content);
} catch (final Exception e) {
throw new MailPreparationException(e);
}
}
}
}
Note: The code of MockMailSender is came from Fahd Shariff.
Then import the TestConfiguration
to your test case.
@RunWith(SpringRunner.class)
@SpringBootTest(classes = AdminApplication.class)
@Import(TestConfigForMail.class)
@WebAppConfiguration
public class OrderTest {
private MockMvc mockMvc;
@Autowired
private OrderService orderService;
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With