What am I doing wrong here? My understanding is Spring should autowire JavaMailSender the way its autowiring EventRepository. Any guidance?
mail.host='smtp.gmail.com' -
mail.port=587
mail.username=username
mail.password=password
mail.properties.mail.smtp.starttls.enable=true
@Service
public class EventService {
private EventRepository eventRepository;
private JavaMailSender javaMailSender;
public EventService(EventRepository eventRepository, JavaMailSender javaMailSender) {
this.eventRepository = eventRepository;
this.javaMailSender = javaMailSender;
}
public Event send(Event event) {
SimpleMailMessage message = new SimpleMailMessage();
message.setText("");
message.setSubject("");
message.setTo("");
message.setFrom("");
javaMailSender.send(message);
return eventRepository.save(event);
}
}
@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationIntegrationTests {
@Autowired
private EventService eventService;
@Test
public void test() throws Exception {
eventService.save(new Event());
}
}
Caused by: 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: {}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1486)
Please make sure that your test reside in the same package
as your main @SpringBootApplication
class.
for example if @SpringBootApplication
class is in src/main/java/some/package
then your @SpringBootTest
need to be in src/test/java/some/package
. If it is not, you need to explicitly set @ComponentScan
to include some.package
. You can also use @SpringBootTest(classes=...)
, @ContextConfiguration(classes=...)}
.
You can also put a @SpringBootConfiguration
class in your test package that scans for your main package.
In my case that was caused by difference in application.properties files in main and test resources.
Following properties were missing in test file:
spring.mail.host=<my host>
spring.mail.port=<my port>
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.connectiontimeout=5000
spring.mail.properties.mail.smtp.timeout=3000
spring.mail.properties.mail.smtp.writetimeout=5000
Please note that it is not best idea to use external services in unit tests.
You should define one of the properties spring.mail.host
or spring.mail.jndi-name
for spring autoconfiguration or define your own bean in your config class.
Check this class org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration
for details.
Example:
@Service
public class MyEmailService {
@Autowired
private JavaMailSender mailSender;
}
import org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration;
@RunWith(SpringRunner.class)
@SpringBootTest(
properties = "spring.mail.host=localhost", // <--- inlined property
classes = {MyEmailService.class, MailSenderAutoConfiguration.class}
)
public class MyEmailServiceTest {
@Autowired
private MyEmailServiceTest emailService;
@Autowire
private JavaMailSender javaMailSender; // if you need
@Test
public void validEmails() {
// some tests of emailService
}
}
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