内の既存のBeanを拾うことができ、エラーをスローしていない私は、次のMavenベースのプロジェクト構造春ブーツの統合は、テスト別のmavenモジュール
product-app
product-web
product-service
product-integration-tests
を持っている私は希望product-service
モジュールで書かれたMailClientService
サービスがありますに統合テストをするのが好きです。統合テストは明らかにproduct-integration-tests
モジュールに書かれています。
product-integration-tests
モジュールのpomには、すでにproduct-web module
が追加されています。
しかし、問題は、統合テストの実行中にMailClientService
のBeanを構築できず、実行時例外がスローされていることです。
例外
13:53:01.161 [main] ERROR org.springframework.test.context.TestContextManager - Caught exception while allowing TestExecutionListener [org.springframework.b[email protected]20b2475a] to prepare test instance [com[email protected]7857fe2]
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.radial.hostedpayments.service.MailClientServiceIntegrationTest': Unsatisfied dependency expressed through field 'mailClientService': No qualifying bean of type [com.radial.hostedpayments.service.MailClientService] found for dependency [com.radial.hostedpayments.service.MailClientService]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.radial.hostedpayments.service.MailClientService] found for dependency [com.radial.hostedpayments.service.MailClientService]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:569) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:349) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:385) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:118) ~[spring-test-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83) ~[spring-test-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.boot.test.autoconfigure.AutoConfigureReportTestExecutionListener.prepareTestInstance(AutoConfigureReportTestExecutionListener.java:46) ~[spring-boot-test-autoconfigure-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:230) [spring-test-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:228) [spring-test-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:287) [spring-test-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) [junit-4.12.jar:4.12]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:289) [spring-test-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:247) [spring-test-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94) [spring-test-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) [junit-4.12.jar:4.12]
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) [junit-4.12.jar:4.12]
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) [junit-4.12.jar:4.12]
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) [junit-4.12.jar:4.12]
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) [junit-4.12.jar:4.12]
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) [spring-test-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) [spring-test-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.junit.runners.ParentRunner.run(ParentRunner.java:363) [junit-4.12.jar:4.12]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191) [spring-test-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:367) [surefire-junit4-2.19.1.jar:2.19.1]
at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:274) [surefire-junit4-2.19.1.jar:2.19.1]
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:238) [surefire-junit4-2.19.1.jar:2.19.1]
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:161) [surefire-junit4-2.19.1.jar:2.19.1]
at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:290) [surefire-booter-2.19.1.jar:2.19.1]
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:242) [surefire-booter-2.19.1.jar:2.19.1]
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:121) [surefire-booter-2.19.1.jar:2.19.1]
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.radial.hostedpayments.service.MailClientService] found for dependency [com.radial.hostedpayments.service.MailClientService]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1406) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1057) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1019) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:566) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
... 30 more
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 1.318 sec <<< FAILURE! - in com.radial.hostedpayments.service.MailClientServiceIntegrationTest
shouldSendMail(com.radial.hostedpayments.service.MailClientServiceIntegrationTest) Time elapsed: 0.002 sec <<< ERROR!
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.radial.hostedpayments.service.MailClientServiceIntegrationTest': Unsatisfied dependency expressed through field 'mailClientService': No qualifying bean of type [com.radial.hostedpayments.service.MailClientService] found for dependency [com.radial.hostedpayments.service.MailClientService]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.radial.hostedpayments.service.MailClientService] found for dependency [com.radial.hostedpayments.service.MailClientService]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.radial.hostedpayments.service.MailClientService] found for dependency [com.radial.hostedpayments.service.MailClientService]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
Results :
Tests in error:
MailClientServiceIntegrationTest.shouldSendMail » UnsatisfiedDependency Error ...
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0
MailClientServiceIntegrationTest.java(製品統合テストのMavenのモジュール)
@RunWith(SpringRunner.class)
public class MailClientServiceIntegrationTest {
@Autowired
private MailClientService mailClientService;
private GreenMail smtpServer;
@Before
public void setUp() throws Exception {
smtpServer = new GreenMail(new ServerSetup(25, null, "smtp"));
smtpServer.start();
}
@Test
public void shouldSendMail() throws Exception {
//given
String recipient = "[email protected]";
String message = "Test message content";
//when
mailClientService.prepareAndSend(recipient, message);
//then
assertReceivedMessageContains(message);
}
private void assertReceivedMessageContains(String expected) throws IOException, MessagingException {
MimeMessage[] receivedMessages = smtpServer.getReceivedMessages();
assertEquals(1, receivedMessages.length);
String content = (String) receivedMessages[0].getContent();
assertTrue(content.contains(expected));
}
@After
public void tearDown() throws Exception {
smtpServer.stop();
}
}
MailClientService.java(製品サービスのMavenモジュール)
@Service
public class MailClientService {
@Autowired
private JavaMailSender mailSender;
private MailContentBuilder mailContentBuilder;
@Value("${error.email.from.address}")
private String emailAddressFrom;
@Value("${error.email.to.address}")
private String emailRecipientAddress;
private String[] emailRecipientAddresses;
private static final boolean HTML_FLAG = true;
private static final String ERROR_ALERT_EMAIL_SUBJECT = "Hosted Payment Service - Error Alert on ";
private static final Logger LOGGER = LoggerFactory.getLogger(MailClientServiceImpl.class);
public MailClientServiceImpl(final JavaMailSender javaMailSender, final MailContentBuilder emailContentBuilder) {
this.mailSender = javaMailSender;
this.mailContentBuilder = emailContentBuilder;
}
@Override
public void prepareAndSend(final String message, final String emailSubject) {
emailRecipientAddresses = StringUtils.split(emailRecipientAddress, ',');
MimeMessagePreparator messagePreparator = mimeMessage -> {
MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage);
messageHelper.setFrom(emailAddressFrom);
messageHelper.setTo(emailRecipientAddresses);
if (StringUtils.isNotBlank(emailSubject)) {
messageHelper.setSubject(emailSubject);
} else {
messageHelper.setSubject(ERROR_ALERT_EMAIL_SUBJECT + CommonUtils.getHostName());
}
// Create the HTML body using Thymeleaf
String htmlContent = mailContentBuilder.buildHtmlTemplating(message);
messageHelper.setText(htmlContent, HTML_FLAG);
};
try {
// Send email
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Sending email '{}' to: {} ", ERROR_ALERT_EMAIL_SUBJECT, emailRecipientAddress);
}
mailSender.send(messagePreparator);
} catch (MailException e) {
e.printStackTrace();
LOGGER.error("Problem with sending alert email to: {}, error message: {}", emailRecipientAddress, e.getMessage());
}
}
@Override
public void prepareAndSend(final String message) {
prepareAndSend(message, null);
}
}
製品-ウェブ/のpom.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<attachClasses>true</attachClasses>
</configuration>
</plugin>
製品統合テスト/のpom.xml
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>hosted-payments</artifactId>
<version>${project.version}</version>
<classifier>classes</classifier>
</dependency>
オクラホマで説明したように代わりにオートワイヤリングの@MockBeanアノテーションを使用することであろう、という考えを得ました。 MailClientServiceは他の2つのクラスを内部的に使用しているので、どのようにしてMailClientServiceを偽装できますか? – user2325154