How to inject MockMvc with multiple objects in Spring Boot REST Junit test case

I have a SpringBoot REST API connecting to Oracle DB.

My controller calls BussinessImpl layer and in-turn BussinessImpl calls multiple DAO layers. (Controller -> BusinessImpl -> DAO1, DAO2,DAO3)

The below test case works perfectly

@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());
  }

But I do not want to hit real database during junit test case. So I wrote a mock.

Working Code

@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");
  }

The above code worked perfectly. In businessImpl class securityAuditDAO.getState returned "somestring". But when I introduced mockMvc.perform it stopped working.

Not Working

 @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());
  }

The above code was still hitting the database. So I realized that I should inject mockMvc with securityAuditDAO so I added the following line

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

Code

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);
  }

I tried injecting securityAuditDAO. But if I do that, my other autowired instances in BusinessImpl were null. How to inject securityAuditDAO without affecting others or how to inject both webApplicationContext and securityAuditDAO. Also tried ReflectionTestUtils.setField but it didn't work as expected.



   
172800
Solving Time
Notaries
Task not challengeable
5 random Notaries
21.01 mBCH
9 or more Confirmations
Created 1552511780685 by
chris

1k




  • Solution/Comments visible for everyone
  • In case of dispute 0.05 notary fee
  • 0.01 site fee + miner fee