Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.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
Spring引导集成测试注入控制器依赖项_Spring_Spring Mvc_Spring Boot_Spring Test_Spring Test Mvc - Fatal编程技术网

Spring引导集成测试注入控制器依赖项

Spring引导集成测试注入控制器依赖项,spring,spring-mvc,spring-boot,spring-test,spring-test-mvc,Spring,Spring Mvc,Spring Boot,Spring Test,Spring Test Mvc,我正在尝试使用Spring Boot编写一个集成测试,测试我的一个控制器中的事务逻辑 测试应执行以下操作: 使用@Inject注入我的一个控制器 将控制器依赖项中的电子邮件依赖项替换为模拟,以避免在集成测试期间实际发送电子邮件 调用控制器的方法 断言当邮件发送模拟抛出异常时,被调用方法的事务被正确回滚 现在我的问题是,当测试运行时,控制器被注入到我的测试类中,但它的所有依赖项都是null。以下是我的集成测试: @RunWith(SpringJUnit4ClassRunner.class) @In

我正在尝试使用Spring Boot编写一个集成测试,测试我的一个控制器中的事务逻辑

测试应执行以下操作:

  • 使用@Inject注入我的一个控制器
  • 将控制器依赖项中的电子邮件依赖项替换为模拟,以避免在集成测试期间实际发送电子邮件
  • 调用控制器的方法
  • 断言当邮件发送模拟抛出异常时,被调用方法的事务被正确回滚
  • 现在我的问题是,当测试运行时,控制器被注入到我的测试类中,但它的所有依赖项都是
    null
    。以下是我的集成测试:

    @RunWith(SpringJUnit4ClassRunner.class)
    @IntegrationTest
    @SpringApplicationConfiguration(App.class)
    @WebIntegrationTest
    public MyIntegrationTest () {
    
        @Inject MyController controller;
    
        @Before
        public void before () {
           // replace one particular dependency of controller with a mock
        }
    
        @Test
        public void testFoo () { ... }
    }
    
    由于该测试是一个启动完整SpringWeb应用程序上下文的集成测试,我希望我的控制器的所有依赖项都已自动连接,但显然不是这样,而是所有依赖项都设置为null

    问题:我是否需要使用一些附加注释,或者在我的
    @Before
    方法中设置一些内容?还是我从一个完全错误的角度看待这个问题


    更新:是否可以测试我的Spring MVC层,而无需通过HTTP(如TestRestTemplate或MockMvc)进行测试?但是直接用
    testrestemplate
    测试而不是注入控制器本身。控制器显然是一个Springbean,但是如果直接将其注入测试类,它将无法初始化上下文

    @RunWith(SpringRunner.class)
    @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = ExampleStart.class)
    public class ExampleTest {
        @Autowired
        private TestRestTemplate restTemplate;
    
        @Test
        public void exampleTest() {
            String body = this.restTemplate.getForObject("/", String.class);
            assertThat(body).isEqualTo("Hello World");
        }
    }
    
    ExampleStart.java->spring boot starter类

    @Configuration
    @ComponentScan
    @EnableAutoConfiguration
    public class ExampleStart extends SpringBootServletInitializer {
        @Override
        protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
            return application.sources(ExampleStart.class);
        }
    
        public static void main(String[] args) {
            SpringApplication.run(ExampleStart.class, args);
        }
    }
    
    参考:


    但是如果您想测试服务方法,您可以使用@Autowired并像往常一样调用这些方法。

    如果我使用
    @Autowire
    @Inject
    将服务类注入到我的测试中,那么同样的事情也会发生。我将服务类注入到测试类中,但是通常使用
    @Autowire
    @Inject
    注入的服务类中的任何依赖项都是
    null
    。例如,我将
    UserService
    注入到我的测试类中。用户服务有一个
    PasswordEncoder
    bean和一个
    UserRepository
    bean,它们都是
    null
    。我已经更新了答案,我刚刚测试了它,它工作得很好。如果您的实际控制器方法有效,那么测试应该有效。看看你错过了什么。我的
    App.class
    包含了主要的方法,非常简单,它只使用
    @SpringBootApplication
    ,没有像你一样的
    配置
    方法。使用
    testrestemplate
    意味着我必须通过HTTP访问我的控制器来测试它,我需要解析这个响应,看看它是否包含我认为相关的字段。没有办法不通过HTTP直接测试我的控制器吗?