Spring Boot 如何在Sping Boot 测试中使用两个不同包中的类?

dy1byipe  于 2023-06-22  发布在  Spring
关注(0)|答案(1)|浏览(140)

我的设置:

  1. Java 20
  2. Sping Boot 3.0.7

原始设置

  1. my.com.app.entities包中的类ProviderManagerClient
    1.类Client引用ProviderManager
  2. Sping Boot 应用程序类如下所示:
@SpringBootApplication(scanBasePackages = "my.com")
public class AppApplication {
    public static void main(String[] args) {
          // many things
    }

    @Bean
    WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**").allowedMethods("*").allowedOrigins("*").allowedHeaders("*").exposedHeaders("Content-Disposition");
            }
        };
    }
}

应用程序上下文在测试期间加载没有问题。集成测试运行良好。

新建设置

1.由于代码重组,类ProviderManager被移动到包my.com.core.entities中(此时,在同一个项目中)。

  1. Client类在my.com.app.entities包中继续,引用了ProviderManager
    没有编译错误(refactorer处理了引用更新),但是在上面的重构之后,集成测试不再运行。对于每个测试,都有一个异常堆栈,如下所示:
java.lang.IllegalStateException: Failed to load ApplicationContext for [WebMergedContextConfiguration@3294102e testClass = my.com.app.ClientRepositoryTest, locations = [], classes = [my.com.app.AppApplication], contextInitializerClasses = [], activeProfiles = ["test-integration"], propertySourceLocations = [], propertySourceProperties = ["org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@6c4906d3, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@4d1bf319, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@17bffc17, org.springframework.boot.test.web.reactive.server.WebTestClientContextCustomizer@55cb6996, org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@1f, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@4b520ea8, org.springframework.boot.test.context.SpringBootTestAnnotation@91305a8a], resourceBasePath = "src/main/webapp", contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Association 'my.com.app.entity.Client.provider' targets an unknown entity named 'my.com.core.Provider'
Caused by: org.hibernate.AnnotationException: Association 'my.com.app.entity.Client.provider' targets an unknown entity named 'my.com.core.Provider'

我的期待
我希望AppApplication类中的注解通知从my.com和更低版本扫描将包括类my.com.core.entities.Providermy.com.core.entities.Manager,但它没有。
我的测试具有以下自定义注解:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@ActiveProfiles("test-integration")
@SpringBootTest(classes = AppApplication.class)
@ExtendWith(CleanUpExtension.class)
public @interface IntegrationTest {
}

我所尝试的

我尝试在my.com.core.config中添加以下配置类:

@Configuration
@ComponentScan
public class CoreConfig {
}

然后我更新了我的测试注解:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@ActiveProfiles("test-integration")
@SpringBootTest(classes = {AppApplication.class, CoreConfig.class})
@ExtendWith(CleanUpExtension.class)
public @interface IntegrationTest {
}

结果

问题仍然存在。
我错过了什么?
先谢谢你了!

68de4m5k

68de4m5k1#

我找到了一个解决方案,但我不知道为什么有必要。我的@IntegrationTest注解最初看起来是这样的:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@ActiveProfiles("test-integration")
@SpringBootTest(classes = AppApplication.class)
@ExtendWith(CleanUpExtension.class)
public @interface IntegrationTest {
}

我必须改进它,通过添加@EntityScan注解来声明在哪里查找实体。现在我的@IntegrationTest注解声明如下所示:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@ActiveProfiles("test-integration")
@SpringBootTest(classes = AppApplication.class)
@ExtendWith(CleanUpExtension.class)
@EntityScan({"my.com.core.entities", "my.com.app.entities"}) // This is the fix!
public @interface IntegrationTest {
}

就是这样!

相关问题