如何使用@ComponentScan和JPA存储库为应用程序编写@SpringBootTest

时间:2019-02-12 21:08:14

标签: spring-boot spring-test

如果使用@ComponentScan和Jpa存储库,我发现编写@SpringBootTest非常困难。有人可以建议吗?这应该是非常琐碎的东西,但是在任何地方都没有记录。

@SpringBootApplication  
@ComponentScan(
        excludeFilters = {
                @ComponentScan.Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
                @ComponentScan.Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) },
        basePackageClasses = {Main.class, Other.class})
public class Main {
    public static void main(String[] args) {
        SpringApplication.run(Main.class, args);
    }
}

和发现的配置类之一具有:

@Configuration
@EnableJpaRepositories("jpa")

现在,我想创建测试,理想情况下,它将仅启用JPA存储库的一个子集,而完全不启用其他任何东西,除非我这样说。即,没有来自生产源代码的配置。这似乎几乎无法表达。这是我能够获得的地方:

@RunWith(SpringRunner.class)
@SpringBootTest
@Import(TestIT.TestConfig.class)
public class TestIT {

    @Configuration
    @EnableJpaRepositories("jpa")
    @AutoConfigureDataJpa
    @AutoConfigurationPackage
    public static class TestConfig {
        //here will be beans for test.
    }

因此此配置会产生错误

java.lang.IllegalArgumentException: Not a managed type ...my jpa repository class

这可能意味着jpa软件包不在自动配置的软件包中。甚至不知道如何添加它。

好的,另一种方法。一些消息来源建议这样做:

@RunWith(SpringRunner.class)
@SpringBootTest
@Import(TestIT.TestConfig.class)
public class TestIT {

    EnableJpaRepositories("jpa")
    @EntityScan(basePackages = "jpa.entities")
    //@TestPropertySource("classpath:application.properties")
    @EnableTransactionManagement
    public static class TestConfig {
        //here will be beans for test.
    }

但此失败并显示caused by: java.lang.IllegalArgumentException: At least one JPA metamodel must be present!

有任何提示吗?

2 个答案:

答案 0 :(得分:0)

首先,没有特别需要在主应用程序启动文件中添加@ComponentScan。 @SpringBootApplication就足够了。

现在关于测试用例: 我使用powermockito来完成所有测试用例,通常如下所示:-

@RunWith(PowerMockRunner.class)
@PowerMockRunnerDelegate(SpringJUnit4ClassRunner.class)
@PrepareForTest({ ContextProvider.class, ConfigurationUtils.class, Utils.class })
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class TestIT {

@PrepareForTest子句中,您会用注解@Mock提及所有类。  例如 无需提及任何repo(我们在其中编写查询的DAO层接口)接口。因此,您的回购声明将是:

private SoftwareRepo softwareRepo;

您将在执行为

时使用它
softwareInventoryRepo = PowerMockito.mock(SoftwareRepo.class);

答案 1 :(得分:0)

好吧,经过大量搜索(徒劳)并且尝试了更多之后,我想我已经回答了。

回顾:

您有主修班(感谢@Bhushan Shinde):

@SpringBootApplication(scanBasePackageClasses = {Main.class, Other.class})
public class Main {
    public static void main(String[] args) {
        SpringApplication.run(Main.class, args);
    }
}

和一些配置:

@Configuration
@EnableJpaRepositories("jpa")
public class Config

因此,要使用SpringBootTest并从头开始配置所有内容进行测试,而忽略生产配置,则可以:

@RunWith(SpringRunner.class)
@SpringBootTest(
        webEnvironment = SpringBootTest.WebEnvironment.NONE,
        classes = TestIT.TestConfig.class)
//@Import(TestIT.TestConfig.class)
public class TestIT {

    @Configuration
    @AutoConfigureDataJpa
    @EnableJpaRepositories("jpa") //fake package names, obviously
    @EntityScan(basePackages = "jpa.entities")
//    @TestPropertySource("classpath:application.properties")
    @EnableTransactionManagement
    public static class TestConfig {
         //test related beans & config.
    }

    //tests here.
}

也许这里还有一些额外的东西,但是经过一天的谷歌搜索和尝试,这对我来说已经足够了。