Как внедрить MockMvc с несколькими объектами в тестовом примере Spring Boot REST Junit - PullRequest
0 голосов
/ 14 марта 2019

У меня есть SpringBoot REST API, соединяющийся с БД Oracle.

Мой контроллер вызывает слой 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());
  }

Приведенный выше код все еще попадал в базу данных.Итак, я понял, что мне нужно ввести mockMvc с securityAuditDAO, поэтому я добавил следующую строку

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, но он не работал должным образом.

...