我很難理解為什么我的JavaMailSender實體沒有被創建,即使我創建了一個顯式的 Bean。IDE 向我展示了一個成功的注入,但是當我運行集成測驗并除錯javaMailSender它的值時,null我總是不管我做什么。
這是我的測驗類,其中@Configuration包含顯式創建JavaMailSenderBean的類。
// MailServiceTest.java
@SpringBootTest
class MailServiceTest {
@Autowired
@Qualifier("testJavaMailSender")
private JavaMailSender javaMailSender;
private final MailService mailService = new MailService(javaMailSender);
private final GreenMail greenMail = new GreenMail();
@BeforeEach
public void setup() {
greenMail.setUser("foo@localhost", "foo", "password");
greenMail.start();
}
@AfterEach
public void teardown() {
greenMail.stop();
}
@Test
public void shouldSendNotificationEmailToRecipient() {
final String expectedText = "An error occured while executing the Jira Connector import sync."
"Please see the log file: 'jira-connector.log' in the application directory";
mailService.notifyAdmin();
final MimeMessage[] receivedMessage = greenMail.getReceivedMessagesForDomain("my-ag.com");
final String actual = GreenMailUtil.getBody(receivedMessage[0]);
assertThat(actual).isEqualTo(expectedText);
}
}
@Configuration
class MailSenderTestConfiguration {
@Bean(name = "testJavaMailSender")
public JavaMailSender testJavaMailSender() {
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
mailSender.setHost("smtp.gmail.com");
mailSender.setPort(587);
mailSender.setUsername("[email protected]");
mailSender.setPassword("password");
Properties props = mailSender.getJavaMailProperties();
props.put("mail.transport.protocol", "smtp");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.debug", "true");
return mailSender;
}
}
我在方法的第一行放置了一個斷點,shouldSendNotificationEmailToRecipient除錯器告訴我javaMailSender = null。有任何想法嗎?我嘗試了 Google 和 Stackoverflow 提供的所有內容。
uj5u.com熱心網友回復:
此測驗通過(全部在一個 .java 檔案中):
@SpringBootTest
class DemoApplicationTests {
@Autowired
@Qualifier("testJavaMailSender")
private JavaMailSender javaMailSender;
@Test
void contextLoads() {
assertNotNull(javaMailSender);
}
}
@Configuration
class MailSenderTestConfiguration {
@Bean(name = "testJavaMailSender")
public JavaMailSender testJavaMailSender() {
// for simplicity/brevity just:
return new JavaMailSenderImpl();
}
}
而這不是(同一個檔案,在第二個斷言中):
@SpringBootTest
class DemoApplicationTests {
@Autowired // this happens "long after" instantiation/construction (of DemoApplicationTests object), but before @Test ;)
@Qualifier("testJavaMailSender")
private JavaMailSender javaMailSender;
// This will be FINALLY assigned, before DemoApplicationTests (object) is even (properly) created/before constructor.
final MailService ms = new MailService(javaMailSender);
@Test
void contextLoads() {
assertNotNull(javaMailSender); // pass!
assertNotNull(ms.ms); // FAILS here!
}
}
@Configuration
class MailSenderTestConfiguration {
@Bean(name = "testJavaMailSender")
public JavaMailSender testJavaMailSender() {
return new JavaMailSenderImpl();
}
}
class MailService {
final JavaMailSender ms;
MailService(JavaMailSender ms) {
this.ms = ms;
}
}
問題:
初始化MailService(在類體中......即“實體初始化器”)!(它是在物件創建(即“構造”)/任何“彈簧魔法”之前完成的。)
解決方案:
初始化MailService,什么時候JavaMailSender可用!
例如移動@Autowired到建構式(測驗):
@SpringBootTest
class DemoApplicationTests {
final MailService ms;
public DemoApplicationTests(@Autowired @Qualifier("testJavaMailSender") JavaMailSender javaMailSender) {
ms = new MailService(javaMailSender);
}
@Test
void contextLoads() {
assertNotNull(ms.ms);
}
}
我什至更喜歡:
@SpringBootTest
class DemoApplicationTests {
@Autowired
private MailService ms;
@Autowired
@Qualifier("testJavaMailSender")
private JavaMailSender javaMailSender;
@Test
void contextLoads() {
assertNotNull(javaMailSender);
assertSame(javaMailSender, ms.ms); //!
}
}
@Configuration
class MailSenderTestConfiguration {
@Bean(name = "testJavaMailSender")
public JavaMailSender testJavaMailSender() {
return new JavaMailSenderImpl();
}
@Bean
public MailService mailService(@Qualifier("testJavaMailSender") JavaMailSender javaMailSender) {
return new MailService(javaMailSender);
}
}
...到MailService春天“管理” 。
uj5u.com熱心網友回復:
配置看起來不錯。我只是在我的本地運行它并且它有效。原因可能是您的 MailSenderTestConfiguration 沒有被呼叫 - 嘗試在 testJavaMailSender() 方法中放置斷點。
我會嘗試使用@SpringBootTest(classes = ....)和/或單獨的@TestConfiguration類來確保測驗加載正確的背景關系與我的測驗配置。
這是我的測驗類(全部在一個檔案中),它作業正常:
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@SpringBootTest
class ApplicationTests {
@Autowired
@Qualifier("testJavaMailSender")
private JavaMailSender javaMailSender;
@BeforeEach
public void setup() {
System.out.println("Do before each!");
}
@AfterEach
public void teardown() {
System.out.println("Do after each!");
}
@Test
public void shouldSendNotificationEmailToRecipient() {
System.out.println(javaMailSender.getMessage());
}
}
@Configuration
class MailSenderTestConfiguration {
@Bean(name = "testJavaMailSender")
public JavaMailSender testJavaMailSender() {
System.out.println("My config works!");
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
return mailSender;
}
}
class JavaMailSenderImpl implements JavaMailSender {
@Override
public String getMessage() {
return "I'm the one you're looking for!";
}
}
interface JavaMailSender {
String getMessage();
}
輸出:
My config works!
......
Do before each!
I'm the one you're looking for!
Do after each!
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/370218.html
