java.lang.AssertionError: Ожидаемый статус: ‹200›, но был: ‹404› в тесте Junit

Я хочу создать тест JUnit для Rest API и создать документ API. Я хочу протестировать этот код:

Контроллер отдыха

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

Интерфейс репозитория

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

    Optional<PaymentTransactions> findById(Integer id);
}

Я попытался реализовать этот тест JUnit5 с помощью 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`"))));
    }
}

Я получаю сообщение об ошибке:

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

Каков правильный способ сделать запрос GET к приведенному выше коду? Возможно, мне нужно добавить ответ OK, когда сообщение отправляется обратно?


person Peter Penzov    schedule 23.12.2018    source источник
comment
статус 404 означает, что ваш запрос на /transactions не найден, можете ли вы использовать `MockMvcRequestBuilders.get(/transactions/{id}, 1) `...   -  person pramesh    schedule 23.12.2018
comment
Я также пробовал это, но я получаю java.lang.AssertionError: Status expected:<200> but was:<404>   -  person Peter Penzov    schedule 23.12.2018
comment
@PeterPenzov Вы проверили, правильно ли инициализируется и внедряется ваш webApplicationContext?   -  person Akash    schedule 24.12.2018
comment
Нет, как я могу это сделать?   -  person Peter Penzov    schedule 24.12.2018


Ответы (4)


привет, в моем случае мне понадобился @MockBean контроллера и всех сервисов, которые были автоматически подключены;)

person Matus Babinsky    schedule 28.06.2021

Это переменная пути, поэтому вместо значения параметра используйте переменную пути.

Для импорта MvcResult вы можете импортировать 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`"))));
person Pradip Karki    schedule 23.12.2018
comment
Я получаю java.lang.AssertionError: Status expected:<200> but was:<404> в этой строке .andExpect(status().isOk()) Есть идеи, почему? - person Peter Penzov; 23.12.2018
comment
Не могли бы вы попробовать добавить строку ниже перед this.mockMvc.perform given(target.findById(anyInt())).willReturn(Optional.of(new PaymentTransactions(1))); и посмотреть, работает ли это? - person Pradip Karki; 23.12.2018
comment
@PeterPenzov конечно, попробуйте. - person Pradip Karki; 24.12.2018
comment
Я пробовал, но снова получаю ошибку 404. Есть идеи, как ее отлаживать? - person Peter Penzov; 24.12.2018
comment
да, вы можете определенно. Я обновил ответ, пожалуйста, посмотрите на него. - person Pradip Karki; 24.12.2018
comment
Знаете ли вы, какие зависимости maven мне нужно импортировать для andReturn();? - person Peter Penzov; 24.12.2018
comment
Кстати, я использую JUnit 5, похоже, ваш код предназначен для JUnit 4? - person Peter Penzov; 24.12.2018
comment
вы можете импортировать import org.springframework.test.web.servlet.MvcResult; вы можете получить библиотеку mvnrepository.com/artifact /org.springframework.boot/. - person Pradip Karki; 24.12.2018
comment
С броском мне удалось это реализовать, но я получаю ошибку компиляции. Этот код, вероятно, для JUnit 4? - person Peter Penzov; 24.12.2018
comment
Да, это в jUnit 4, но идея в том, что вы можете распечатывать и отлаживать результаты, используя MvcResult и другие полезные методы. - person Pradip Karki; 24.12.2018
comment
один пример, который я нашел с использованием jUnit 5: 5 с методом контроллера junit 5 mockito возвращает null"> stackoverflow.com/questions/48727758/, но он должен быть таким же. Можете ли вы также опубликовать сообщение об ошибке компиляции? и ваш URL должен быть похож на /transactions/1 - person Pradip Karki; 24.12.2018

Можешь попробовать это..

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());
}
}
person pramesh    schedule 25.12.2018
comment
Я получаю NPE в этой строке MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get("/transactions/{id}", 1)) - person Peter Penzov; 25.12.2018
comment
можете ли вы заменить этот код в своей настройке, я думаю, что PaymentTransactionsController не внедряется в ваш тест, поэтому вы получаете NPE @Before public void setUp() { MockitoAnnotations.initMocks(this); mvc = MockMvcBuilders.standaloneSetup(new PaymentTransactionRepository()).build(); } - person pramesh; 26.12.2018
comment
у меня есть небольшая демонстрация для модульного теста в моем репозитории git... она может вам помочь.. github. com/prameshbhattarai/spring-boot-demo - person pramesh; 26.12.2018
comment
Я снова получаю NPE в той же строке. - person Peter Penzov; 26.12.2018
comment
можете ли вы предоставить мне трассировку стека для вашего исключения... также вы проверили мой репозиторий.. - person pramesh; 26.12.2018
comment
Вот результат: pastebin.com/06b7XsFH Сегодня я протестирую ваш пример кода. - person Peter Penzov; 26.12.2018

Вместо @PostMapping и @GetMapping, которые вызвали ту же проблему, в то время как @RequestMapping в контроллере помог

person Parameshwar    schedule 24.07.2020