3

こんにちは、単純なアプリケーションを手に入れたので、いくつかの統合テストを作成しようとしています。そのため、JUnit テストで springboot を使用しており、テスト開発と本番用にわずかに異なる構成が必要なため、プロファイルを使用しています。私の問題は、アプリケーションをスタンドアロンの tomcat サーバーにデプロイすると、プロファイルが完全に機能することです。ただし、springboot で JUnit テストを開始すると、アプリケーションはすべてのプロファイル構成を読み込もうとするため、競合が発生します。

「タイプ 'org.springframework.context.MessageSource' の適格な Bean がありません: 単一の一致する Bean が期待されていましたが、2 つ見つかりました」

すでに述べたように、これはスタンドアロンの tomcat で動作します。

ここに私のコードのスニペットがあります:

これは私のテストクラスです

@ActiveProfiles(ProfileConstants.TEST)
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(webEnvironment =     SpringBootTest.WebEnvironment.RANDOM_PORT, classes = {SpringBootInitializer.class})
public class MyTest

次に、SpringBootInitializer

@Configuration
@EnableAutoConfiguration
@Import(WebAppConfig.class)
public class SpringBootInitializer extends SpringBootServletInitializer implements ServletContextAware
{

  /**
   * this method will force the embedded tomcat to load the jsf-configuration
   * 
   * @param servletContext the servletcontext of embedded tomcat
   */
  @Override
  public void setServletContext(ServletContext servletContext)
  {
    // sets the spring default initialization profile to test
    servletContext.setInitParameter("spring.profiles.active", ProfileConstants.TEST);
    // will ensure, that the context-initialization is executed. If not set to true the jsf-config will not be
    // loaded
    servletContext.setInitParameter("com.sun.faces.forceLoadConfiguration", "true");
    // will initialize jsf-context
    servletContext.addListener(com.sun.faces.config.ConfigureListener.class);
  }

  /**
   * registration of the {@link FacesServlet} with url mappings to .xhtml, .jsf and .faces
   * 
   * @return the ServletRegistrationBean with registered {@link FacesServlet}
   */
  @Bean
  public ServletRegistrationBean facesServletRegistration()
  {
    ServletRegistrationBean registration = new ServletRegistrationBean(new FacesServlet(), "*.xhtml", "*.jsf",
                                                                       "*.faces");
    registration.setLoadOnStartup(1);
    return registration;
  }
}

そして最後に私の WebAppConfig.class

@Configuration
@ComponentScan({"my.component.package"})
@EnableWebMvc
public class WebAppConfig extends WebMvcConfigurerAdapter
{
    ...
    /**
     * spring locale. the resource-bundles will be set here . <br>
     * also the {@link MessageReaderHolder} will be initialized here that holds a static default implementation
     * to read the messages from the resource bundles.
     *
     * @return the resource bundles
     */
    @Profile({ ProfileConstants.PRODUCTION, ProfileConstants.TEST})
    @Bean(name = "messageSource")
    public MessageSource messageSourceProduction()
    {
      ReloadableResourceBundleMessageSource bundleMessageSource = new ReloadableResourceBundleMessageSource();
      bundleMessageSource.setBasenames("classpath:locale");
      MessageReaderHolder.initialize(bundleMessageSource);
      return bundleMessageSource;
    }

    /**
     * spring locale. the resource-bundles will be set here . <br>
     * also the {@link MessageReaderHolder} will be initialized here that holds a static default implementation
     * to read the messages from the resource bundles.
     *
     * @return the resource bundles
     */
    @Profile({ ProfileConstants.DEVELOPMENT})
    @Bean(name = "messageSource")
    public MessageSource messageSourceDevelopment()
    {
      ReloadableResourceBundleMessageSource bundleMessageSource = new ReloadableResourceBundleMessageSource();
      bundleMessageSource.setBasenames("classpath:locale");
      bundleMessageSource.setCacheSeconds(30); 
      MessageReaderHolder.initialize(bundleMessageSource);
      return bundleMessageSource;
    }
}

使用するプロファイルに基づいて、1 つの messageSource のみが構成に読み込まれることを期待します。私は常に 1 つのプロファイルのみを使用しているため、アプリケーションは重複する Bean をロードするべきではありませんが、ロードします。

なぜこれが起こるのですか?この問題の手がかりが見つかりません...

4

0 に答える 0