【问题标题】:Spring Boot: Inject mock in ApplicationRunnerSpring Boot:在 ApplicationRunner 中注入模拟
【发布时间】:2020-05-23 23:15:17
【问题描述】:

我正在尝试进行集成测试,其中包括 ApplicationRunner 的执行。

我用的是@SpringBootTest,在上下文初始化的时候,ApplicationRunner自动启动,还可以。

我想要实现的是在 ApplicationRunner 中注入一个 Mock 并在 ApplicationRunner 执行之前配置该模拟。

如果我在测试中配置mock是不行的,因为到执行测试的时候,Spring上下文已经被初始化并且ApplicationRunner已经被执行了。

有没有办法配置模拟 Spring 上下文已初始化,之前 ApplicationRunner 被执行?

【问题讨论】:

  • 能否请您添加有关 ApplicationRunner 实施和测试的来源
  • 这个问题比较概念化,具体实现应该无关...
  • 我想您正在使用 springBootTests 而不配置您要测试的特定类。所以 spring 在上下文中启动所有 bean,包括你想要模拟的依赖项。为避免这种情况,您必须仅将要测试的 bean 和所有依赖项指定为 mockBean。但是,没有看到来源是不可能确认的。
  • 是的!我想模拟一个依赖项,并在执行 ApplicationRunner 之前配置该模拟。我无法实现这一点,因为 ApplicationRunner 是在流控制到达 Test 类之前执行的。
  • @Mr.Eddart 其实我还是没完全理解你。但是,我添加了我暗示的答案。因此,您可以查看它是否满足您的需求,或者我们如何改进它以满足您的需求。谢谢。

标签: java spring spring-boot junit4 junit5


【解决方案1】:

如果您的 ApplicationRunner 类有 bean 依赖项,您可以按如下方式模拟它。

import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest   
public class ApplicationRunnerTest {
    @MockBean
    private final Dependency dependency;
    @Autowired
    private final ApplicationRunner applicationRunner;

    @Before
    public void setUp() throws Exception {
    }

    @Test
    public void testMethod() {
    }
}

【讨论】:

  • 在提供代码 sn-p 时,包含 import 语句会很有帮助。 :)
  • @mre 同意.. 在这种情况下,只是认为它很含蓄。无论如何添加.. thnx :)
  • 谢谢,但我指定我不仅要模拟依赖项,还要在 ApplicationRunner 执行之前配置其行为(在调用 Test 方法之前执行,因此在我之前有机会配置模拟)...
  • @Mr.Eddart 你的观点很不清楚。请问在调用测试方法之前它是如何执行的?
  • @Mr.Eddart 请提供您的代码以了解 ApplicationRunner 的执行,因为您提到的场景听起来很奇怪
【解决方案2】:

希望这能回答您的问题

当我们尝试执行一个测试用例时,这里的 webApplicationContext 会被初始化为 @Before 被启动,它调用了具有 webApplicationContext 初始化逻辑的 AbstractTest 类的 setUp()

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = Main.class)
@WebAppConfiguration
public abstract class AbstractTest {

   protected MockMvc mvc;
   @Autowired
   WebApplicationContext webApplicationContext;

   protected void setUp() {
      mvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
   }

   protected String mapToJson(Object obj) throws JsonProcessingException {
      ObjectMapper objectMapper = new ObjectMapper();
      return objectMapper.writeValueAsString(obj);
   }
   protected <T> T mapFromJson(String json, Class<T> clazz)
      throws JsonParseException, JsonMappingException, IOException {

      ObjectMapper objectMapper = new ObjectMapper();
      return objectMapper.readValue(json, clazz);
   }
}


public class UserControllerTest extends AbstractTest {
   @Override
   @Before
   public void setUp() {
      super.setUp();
   }
   @Test
   public void testGet() throws Exception {
      String uri = “/url”;
      MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.get(uri)
         .accept(MediaType.APPLICATION_JSON_VALUE)).andReturn();

      int status = mvcResult.getResponse().getStatus();
      assertEquals(200, status);
   }

}

主 Spring 引导类

@SpringBootApplication
public class Main extends SpringBootServletInitializer{

    private Logger LOGGER = (Logger) LoggerFactory.getLogger(FactsMain.class);

    @Value("${facts.trustCertPath}")
    private String trustCertPath;


    public static void main(String args[]) {
        SpringApplication.run(Main.class, args);
    }

    @Override
     protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
      return application.sources(FactsMain.class);
     }

    @PostConstruct
    public void setSSLPath() {

        LOGGER.info("trustCertPath - " + trustCertPath);
        System.setProperty("javax.net.ssl.trustStore", trustCertPath);
    }
}

【讨论】:

  • 谢谢。但我认为这并没有回答这个问题,因为它没有考虑到上述 ApplicationRunner 的执行。
  • 你可以选择 SpringJUnit4ClassRunner 而不是 SpringRunner,因为它将启用测试所需的更多功能
猜你喜欢
  • 2021-05-28
  • 2017-07-03
  • 1970-01-01
  • 2019-06-16
  • 2017-07-30
  • 1970-01-01
  • 1970-01-01
  • 2017-07-29
  • 2015-04-25
相关资源
最近更新 更多