首页 > 解决方案 > 如何在 Spring Boot REST Junit 测试用例中注入具有多个对象的 MockMvc

问题描述

我有一个连接到 Oracle DB 的 SpringBoot REST API。

我的控制器调用 BusinessImpl 层,然后 BusinessImpl 调用多个 DAO 层(Controller -> BusinessImpl -> DAO1, DAO2, DAO3

以下测试用例完美运行

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration()
@TestPropertySource("classpath:dev-manifest.yml")
@ContextConfiguration(classes = Application.class)
@ConfigurationProperties(prefix = "env")
@SpringBootTest
public class MyTest
{
  private static final String REQUEST_URI = "/v1/registration/accounts/links";
  private MediaType contentType = new MediaType(MediaType.APPLICATION_JSON.getType(),
      MediaType.APPLICATION_JSON.getSubtype(), Charset.forName("utf8"));

  private MockMvc mockMvc;

  @Autowired
  private WebApplicationContext webApplicationContext;

  @Before
  public void setup()
  {
    this.mockMvc = webAppContextSetup(webApplicationContext).build();
  }

  @Test
  public void testSave()
  {
      String testInput = "some json input";
      mockMvc.perform(post(REQUEST_URI).content(testInput).contentType(contentType))
          .andExpect(status().isOk());
  }

但我不想在 junit 测试用例期间访问真实数据库。所以我写了一个模拟。

工作代码

  @Mock
  private SecurityAuditDAO securityAuditDAO;

  @InjectMocks
  private RegistrationBusinessImpl registrationBusinessImpl;

  @Test
  public void testSave()
  {
      when(securityAuditDAO.getState(Mockito.any())).thenReturn("somestring");
      SomeRequest someRequest = new SomeRequest();
      someRequest.setStatus("SUCCESS");
      SomeResponse status = registrationBusinessImpl.createUser(SomeRequest, "127.0.0.1");
  }

上面的代码完美运行。在 businessImpl 类 securityAuditDAO.getState 中返回“somestring”。但是当我介绍 mockMvc.perform 它停止工作。

不工作

  @Test
  public void testSave()
  {
      when(securityAuditDAO.getState(Mockito.any())).thenReturn("somestring");
      String testInput = "some json input";
      mockMvc.perform(post(REQUEST_URI).content(testInput).contentType(contentType))
          .andExpect(status().isOk());
  }

上面的代码仍在访问数据库。所以我意识到我应该用 securityAuditDAO 注入 mockMvc 所以我添加了以下行

this.mockMvc = MockMvcBuilders.standaloneSetup(securityAuditDAO).build();

代码

  private MockMvc mockMvc;

  @Autowired
  private WebApplicationContext webApplicationContext;

  @Mock
  private SecurityAuditDAO securityAuditDAO;

  @InjectMocks
  private RegistrationBusinessImpl registrationBusinessImpl;

  @InjectMocks
  RegistrationApiController registrationApiController;  

  @Before
  public void setup()
  {
    MockitoAnnotations.initMocks(this);
    //this.mockMvc = webAppContextSetup(webApplicationContext).build();
    this.mockMvc = MockMvcBuilders.standaloneSetup(securityAuditDAO).build();
    //this.mockMvc = MockMvcBuilders.standaloneSetup(registrationApiController).build();
    //ReflectionTestUtils.setField(mockMvc, "securityAuditDAO", securityAuditDAO);
  }

我尝试注入 securityAuditDAO。但如果我这样做,我在 BusinessImpl 中的其他自动装配实例为空。如何在不影响其他人的情况下注入 securityAuditDAO,或者如何同时注入 webApplicationContext 和 securityAuditDAO。还尝试了 ReflectionTestUtils.setField 但它没有按预期工作。

标签: spring-bootjunitmockingmockito

解决方案


推荐阅读