Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在Spring Boot JUnit测试中排除*自动配置类?_Java_Spring_Junit_Spring Boot - Fatal编程技术网

Java 如何在Spring Boot JUnit测试中排除*自动配置类?

Java 如何在Spring Boot JUnit测试中排除*自动配置类?,java,spring,junit,spring-boot,Java,Spring,Junit,Spring Boot,我试过: @RunWith(SpringJUnit4ClassRunner.class) @EnableAutoConfiguration(exclude=CrshAutoConfiguration.class) @SpringApplicationConfiguration(classes = Application.class) @WebAppConfiguration public class LikeControllerTest { 然而,崩溃仍然启动。虽然目前它不会损害测试,我希望在

我试过:

@RunWith(SpringJUnit4ClassRunner.class)
@EnableAutoConfiguration(exclude=CrshAutoConfiguration.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
public class LikeControllerTest {

然而,崩溃仍然启动。虽然目前它不会损害测试,我希望在单元测试期间禁用不必要的模块,以加快速度并避免潜在的冲突。

我认为,如果您使用
@SpringApplicationConfiguration
加载
应用程序
类,那么在测试类上使用
@EnableAutoConfiguration
注释将不起作用。问题是,
应用程序
类中已经有了一个
@EnableAutoConfiguration
注释,它不排除
CrshAutoConfiguration
Spring
使用该注释而不是测试类中的注释来自动配置bean

我认为最好的选择是在测试中使用不同的应用程序上下文,并排除该类中的
CrshAutoConfiguration


我做了一些测试,如果您使用
@SpringApplicationConfiguration
注释和
SpringJUnit4ClassRunner
我有一个类似的用例,我想单独测试一个springboot配置的存储库,那么测试类上的
@EnableAutoConfiguration
就完全被忽略了(在我的情况下,没有Spring安全自动配置,测试失败)。
@SpringApplicationConfiguration
使用
SpringApplicationContextLoader
,并且有一个JavaDoc声明

可用于测试非web功能(如存储库层)或 启动一个完全配置的嵌入式servlet容器

但是,与您一样,我无法理解如何使用主配置入口点,即使用
@SpringApplicationConfiguration(classes=Application.class)
的方法,将测试配置为仅测试存储库层

我的解决方案是创建一个用于测试的全新应用程序上下文

  • repoigrationtest.java
  • TestRepoConfig.java
  • 其中
    repoigrationtest.java
    具有

    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringApplicationConfiguration(classes = TestRepoConfig.class)
    public class RepoIntegrationTest {
    
    @SpringBootApplication(exclude = SecurityAutoConfiguration.class)
    public class TestRepoConfig {
    
    而且
    TestRepoConfig.java

    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringApplicationConfiguration(classes = TestRepoConfig.class)
    public class RepoIntegrationTest {
    
    @SpringBootApplication(exclude = SecurityAutoConfiguration.class)
    public class TestRepoConfig {
    

    这让我摆脱了麻烦,但如果Spring Boot团队中的任何人都能提供一个推荐的替代解决方案,这将非常有用。

    遇到了同样的问题,在测试期间无法排除主Spring Boot类。使用以下方法解决了它

    不要使用@SpringBootApplication,而是使用它包含的所有三个注释,并将名称分配给@Configuration

    @Configuration("myApp")
    @EnableAutoConfiguration
    @ComponentScan
    public class MyApp { .. }
    
    在测试类中,使用完全相同的名称定义配置:

    @RunWith(SpringJUnit4ClassRunner.class)
    @WebAppConfiguration
    // ugly hack how to exclude main configuration
    @Configuration("myApp")
    @SpringApplicationConfiguration(classes = MyTest.class)
    public class MyTest { ... }
    

    这应该会有帮助。如果有更好的方法来禁用配置注释的自动扫描,那就太好了。

    我也在努力解决这个问题,在粗略阅读文档后,找到了一个简单的模式来隔离测试上下文

    /**
    *键入{@link#basePackages}的安全替代项以指定包
    *扫描带注释的组件。将扫描每个指定类别的包。
    *考虑在每个包中创建一个特殊的无操作标记类或接口
    *除了被此属性引用之外,没有其他用途。
    */
    Class[]basePackageClasses()默认值{};

  • 为spring测试创建一个包,
    (“com.example.test”)
  • 在包中创建标记接口作为上下文限定符
  • 将标记接口引用作为参数提供给BasePackageClass

  • 范例


    IsolatedTest.java

    package com.example.test;
    
    @RunWith(SpringJUnit4ClassRunner.class)
    @ComponentScan(basePackageClasses = {TestDomain.class})
    @SpringApplicationConfiguration(classes = IsolatedTest.Config.class)
    public class IsolatedTest {
    
         String expected = "Read the documentation on @ComponentScan";
         String actual = "Too lazy when I can just search on Stack Overflow.";
    
          @Test
          public void testSomething() throws Exception {
              assertEquals(expected, actual);
          }
    
          @ComponentScan(basePackageClasses = {TestDomain.class})
          public static class Config {
          public static void main(String[] args) {
              SpringApplication.run(Config.class, args);
          }
        }
    }
    
    ...
    
    TestDomain.java

    package com.example.test;
    
    public interface TestDomain {
    //noop marker
    }
    

    我有一个类似的问题,但我找到了一个可能帮助其他人的不同解决方案。我使用Spring配置文件来分离测试和应用程序配置类

  • 创建一个具有特定概要文件的TestConfig类,并在此处从组件扫描中排除任何应用程序配置

  • 在测试类中,将概要文件设置为与TestConfig匹配,并使用@ContextConfiguration注释将其包括在内

  • 例如:

    配置:

    @Profile("test")
    @Configuration
    @EnableWebMvc
    @ComponentScan(
        basePackages="your.base.package",
        excludeFilters = {
                @Filter(type = ASSIGNABLE_TYPE,
                        value = {
                                ExcludedAppConfig1.class,
                                ExcludedAppConfig2.class
                })
        })
    public class TestConfig { ...}
    
    @SpringBootTest(classes = {Application.class}) //won't component scan your configuration because it doesn't have an autowire-able annotation
    //Other annotations here
    public class TestThatUsesNormalApplication {
        //my test code
    }
    
    @SpringBootTest(classes = {TestConfiguration.class}) //this still works!
    //Other annotations here
    public class TestThatUsesCustomTestConfiguration {
        //my test code
    }
    
    测试:


    另一种排除自动配置类的简单方法

    将以下类似配置添加到您的应用程序.yml文件中

    ---
    spring:
      profiles: test
      autoconfigure.exclude: org.springframework.boot.autoconfigure.session.SessionAutoConfiguration
    
    对于新的注释,我采用并修改了它,使其使用带有
    @SpringBootApplication
    配置类的概要文件。
    @Profile
    注释是必需的,因此该类仅在需要它的特定集成测试期间被拾取,因为其他测试配置执行不同的组件扫描

    以下是配置类:

    @Profile("specific-profile")
    @SpringBootApplication(scanBasePackages={"com.myco.package1", "com.myco.package2"})
    public class SpecificTestConfig {
    
    }
    
    @RunWith(SpringRunner.class)
    @SpringBootTest(classes = { SpecificTestConfig.class })
    @ActiveProfiles({"specific-profile"})
    public class MyTest {
    
    }
    
    然后,测试类引用此配置类:

    @Profile("specific-profile")
    @SpringBootApplication(scanBasePackages={"com.myco.package1", "com.myco.package2"})
    public class SpecificTestConfig {
    
    }
    
    @RunWith(SpringRunner.class)
    @SpringBootTest(classes = { SpecificTestConfig.class })
    @ActiveProfiles({"specific-profile"})
    public class MyTest {
    
    }
    

    如果Spring Boot 1.4.x及更高版本出现此问题,您可以使用
    @OverrideAutoConfiguration(enabled=true)
    来解决此问题

    与这里的提问/回答类似


    参考:

    如果问题是您引入的SpringBootApplication/配置正在扫描您的测试配置所在的包,那么您实际上可以从测试配置中删除@Configuration注释,并且您仍然可以在@SpringBootTest注释中使用它们。例如,如果您有一个类Applica选项是您的主配置,类TestConfiguration是特定(但不是所有)测试的配置,您可以按如下方式设置类:

    @Import(Application.class) //or the specific configurations you want
    //(Optional) Other Annotations that will not trigger an autowire
    public class TestConfiguration {
        //your custom test configuration
    }
    
    然后,您可以通过以下两种方式之一配置测试:

  • 对于常规配置:

    @Profile("test")
    @Configuration
    @EnableWebMvc
    @ComponentScan(
        basePackages="your.base.package",
        excludeFilters = {
                @Filter(type = ASSIGNABLE_TYPE,
                        value = {
                                ExcludedAppConfig1.class,
                                ExcludedAppConfig2.class
                })
        })
    public class TestConfig { ...}
    
    @SpringBootTest(classes = {Application.class}) //won't component scan your configuration because it doesn't have an autowire-able annotation
    //Other annotations here
    public class TestThatUsesNormalApplication {
        //my test code
    }
    
    @SpringBootTest(classes = {TestConfiguration.class}) //this still works!
    //Other annotations here
    public class TestThatUsesCustomTestConfiguration {
        //my test code
    }
    
  • 使用测试自定义测试配置:

    @Profile("test")
    @Configuration
    @EnableWebMvc
    @ComponentScan(
        basePackages="your.base.package",
        excludeFilters = {
                @Filter(type = ASSIGNABLE_TYPE,
                        value = {
                                ExcludedAppConfig1.class,
                                ExcludedAppConfig2.class
                })
        })
    public class TestConfig { ...}
    
    @SpringBootTest(classes = {Application.class}) //won't component scan your configuration because it doesn't have an autowire-able annotation
    //Other annotations here
    public class TestThatUsesNormalApplication {
        //my test code
    }
    
    @SpringBootTest(classes = {TestConfiguration.class}) //this still works!
    //Other annotations here
    public class TestThatUsesCustomTestConfiguration {
        //my test code
    }
    

  • 一天来,我一直在为一个类似的问题苦苦挣扎……我的设想是:

    我有一个SpringBoot应用程序,我在
    scr/main/resource中使用applicationContext.xml