3

I want to create JUnit test for Rest api and generate api doc. I want to test this code:

Rest controller

@RestController
@RequestMapping("/transactions")
public class PaymentTransactionsController {

@Autowired
private PaymentTransactionRepository transactionRepository;

@GetMapping("{id}")
    public ResponseEntity<?> get(@PathVariable String id) {
        return transactionRepository
                .findById(Integer.parseInt(id))
                .map(mapper::toDTO)
                .map(ResponseEntity::ok)
                .orElseGet(() -> notFound().build());
    }
}

Repository interface

public interface PaymentTransactionRepository extends CrudRepository<PaymentTransactions, Integer>, JpaSpecificationExecutor<PaymentTransactions> {

    Optional<PaymentTransactions> findById(Integer id);
}

I tried to implement this JUnit5 test with mockito:

@ExtendWith({ RestDocumentationExtension.class, SpringExtension.class })
@SpringBootTest(classes = PaymentTransactionsController.class)
@WebAppConfiguration
public class PaymentTransactionRepositoryIntegrationTest {
    .....
    private MockMvc mockMvc;

    @MockBean
    private PaymentTransactionRepository transactionRepository;

    @BeforeEach
    void setUp(WebApplicationContext webApplicationContext,
              RestDocumentationContextProvider restDocumentation) {

        PaymentTransactions obj = new PaymentTransactions(1);

        Optional<PaymentTransactions> optional = Optional.of(obj);      

        PaymentTransactionRepository processor = Mockito.mock(PaymentTransactionRepository.class);
        Mockito.when(processor.findById(Integer.parseInt("1"))).thenReturn(optional);       

        this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
              .apply(documentationConfiguration(restDocumentation))
              .alwaysDo(document("{method-name}", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint())))
              .build();
    }

    @Test
    public void testNotNull() {
        assertNotNull(target);
    }

    @Test
    public void testFindByIdFound() {
        Optional<PaymentTransactions> res = target.findById(Integer.parseInt("1"));
//        assertTrue(res.isPresent());
    }

    @Test
    public void indexExample() throws Exception {
            this.mockMvc.perform(get("/transactions").param("id", "1"))
                .andExpect(status().isOk())
                .andExpect(content().contentType("application/xml;charset=UTF-8"))
                .andDo(document("index-example", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()), links(linkWithRel("crud").description("The CRUD resource")), responseFields(subsectionWithPath("_links").description("Links to other resources")),
                    responseHeaders(headerWithName("Content-Type").description("The Content-Type of the payload, e.g. `application/hal+json`"))));
    }
}

I get error:

java.lang.AssertionError: Status expected:<200> but was:<404>

What his the proper way to to make GET request to the above code? Probably I need to add response OK when message is send back?

Peter Penzov
  • 1,126
  • 134
  • 430
  • 808

4 Answers4

2

hi in my case i needed @MockBean of controller and all services that is was autowireing ;)

1

Instead of @PostMapping and @GetMapping which caused same problem while @RequestMapping in controller helped

Parameshwar
  • 856
  • 8
  • 16
0

It's a path variable, so instead of using param value, please use path variable.

For MvcResult import, you can import org.springframework.test.web.servlet

import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;

...

given(target.findById(anyInt())).willReturn(Optional.of(new PaymentTransactions(1))).andReturn();

MvcResult result = this.mockMvc.perform(get("/transactions/1")
                .accept("application/xml;charset=UTF-8")).andReturn();

String content = result.getResponse().getContentAsString();

this.mockMvc.perform(get("/transactions/1")
            .accept("application/xml;charset=UTF-8"))
            .andExpect(status().isOk())
            .andDo(document("index-example", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()), links(linkWithRel("crud").description("The CRUD resource")), responseFields(subsectionWithPath("_links").description("Links to other resources")),
                responseHeaders(headerWithName("Content-Type").description("The Content-Type of the payload, e.g. `application/hal+json`"))));
Pradip Karki
  • 662
  • 1
  • 8
  • 21
0

Can you try this..

public class PaymentTransactionsControllerTest {

private MockMvc mvc;

@InjectMocks
PaymentTransactionsController paymentTransactionsController;

@MockBean
private PaymentTransactionRepository processor;

@Before
public void setUp() {
    MockitoAnnotations.initMocks(this);
    mvc = MockMvcBuilders.standaloneSetup(paymentTransactionsController).build();
}

@Test
public void indexExample() throws Exception {

    PaymentTransactions obj = new PaymentTransactions(1);
    Optional<PaymentTransactions> optional = Optional.of(obj);  

    Mockito.when(processor.findById(Integer.parseInt("1"))).thenReturn(optional); 

    MvcResult result = mvc.perform(MockMvcRequestBuilders.get("/transactions/{id}", 1))
            .andDo(print())
            .andExpect(status().isOk())
            .andReturn();

    Assert.assertNotNull(result.getResponse().getContentAsString());
}
}
pramesh
  • 501
  • 3
  • 11
  • I get NPE at this line `MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get("/transactions/{id}", 1))` – Peter Penzov Dec 25 '18 at 09:09
  • can you replace by this code in your setup, i think PaymentTransactionsController is not injected in your test so you are getting NPE `@Before public void setUp() { MockitoAnnotations.initMocks(this); mvc = MockMvcBuilders.standaloneSetup(new PaymentTransactionRepository()).build(); }` – pramesh Dec 26 '18 at 07:44
  • i have small demo for unit test in my git repo... it can help you.. https://github.com/prameshbhattarai/spring-boot-demo – pramesh Dec 26 '18 at 07:47
  • I get again NPE at the same line. – Peter Penzov Dec 26 '18 at 08:45
  • can you provide me the stack trace for your exception... also did you check my repo.. – pramesh Dec 26 '18 at 09:09
  • Here is the output: https://pastebin.com/06b7XsFH I will test your code example today. – Peter Penzov Dec 26 '18 at 13:18