0
0

More than 1 year has passed since last update.

SpringBoot コントローラの単体テストでエラー 原因は@WebMvcTestの引数不足

Last updated at Posted at 2022-12-10

症状

次のテストメソッドを実行

OrderRestCntrollerTest.java
package com.example.restapi.order;

import com.example.restapi.domain.cartItem.CartItemService;
import com.example.restapi.domain.customer.CustomerService;
import com.example.restapi.domain.order.OrderService;
import com.example.restapi.implement.cartItem.CartItemDto;
import com.example.restapi.implement.order.OrderDto;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;

import javax.servlet.http.HttpServletRequest;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;

@WebMvcTest
public class OrderRestControllerTest {

    @Autowired
    private MockMvc mockMvc;
    @MockBean
    private CustomerService customerService;
    @MockBean
    private  OrderService orderService;
    @MockBean
    private CartItemService cartItemService;


    @Test
    @DisplayName("HttpResponseを引数とし、Createを実行したとき、注文情報がJson形式で返される。")
    public void givenHttpResponse_whenCreate_thenReturnOrderbyJson() throws Exception {
        // given-precondition or Setup


        // make mock in customerId from HttpResponse
        //HttpResponse -> Jwt -> customerId(Email)
        HttpServletRequest request = null;
        Integer customerId = Mockito.doReturn(3).when(customerService.getIdfromJwtToken(request));
        // make mock in cartItem
        List<CartItemDto> cartItemDtos = new ArrayList<>();
        cartItemDtos.add(new CartItemDto(1,3,3,5));
        cartItemDtos.add(new CartItemDto(1,3,7,1));
        cartItemDtos.add(new CartItemDto(1,3,10,9));
        cartItemDtos.add(new CartItemDto(1,3,13,9));
        cartItemDtos.add(new CartItemDto(1,3,15,3));
        Mockito.doReturn(cartItemDtos).when(cartItemService.listCartItems(customerId));
        //  make mock in Order create
        OrderDto expectedOrderDto = new OrderDto(10,3,toDate(LocalDateTime.now()),3900f,300f,4200f,390f,4590f, "pending");

        //when - action or the behavior that we are going test
       ResultActions response = mockMvc.perform(get("/api/product",request));
//
//        //then - verify the output
//        response.andExpect(status().isOk())
//                .andDo(print());
    }
    private Date toDate(LocalDateTime localDateTime) {
        ZoneId zone = ZoneId.systemDefault();
        ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, zone);
        Instant instant = zonedDateTime.toInstant();
        return Date.from(instant);
    }
}

実行結果

error.txt(一部抜粋)
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'customerRestController': Unsatisfied dependency expressed through field 'authenticationManager'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.security.authentication.AuthenticationManager' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}


違うドメインのエラーがでるのかが違和感があると思いした。
今実装しているドメインがorderなのに、customerRestControllerでエラーが出るのが変です。

原因

@WebMvcTestの引数が不足しているのが原因
引数無しで@webMvcTestを指定すると 全て の@RestControllerのアノテーションを参照する。
私は今までコントローラーの単体テストを書いていなく、それを突っ込まれたようです。

原因となるドメインの@RestControllerを片っ端からコメントアウトすると、症状は解消することで確認

対策

@WebMvcTestでテストしたいドメインのコントローラーを指定する。

WebMvcAnnotation.java

// 引数なしだとすべての@RestControllerを拾ってしまう。
@WebMvcTest


// 引数ありだと引数だけのクラスの@RestControllerを参照する。
@WebMvcTest(OrderRestController.class)


感想

私の様にコントローラの単体テストを後回しにしていたら直面するエラーだと思います。
よく直面するDIコンテナに値入ってない問題とは別のものなので 盲点でした。

参考

image.png

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0