2017-12-27 29 views
1

컨트롤러 용 단위 테스트를 쓰고 있습니다. 나는 서비스 레이어를 조롱하고 나머지 컨트롤러에 독립형 설정을 사용하고 있습니다.스프링 부트의 모든 테스트 케이스 전에 독립형 컨트롤러를 한 번만 설치하는 방법은 무엇입니까?

ProductSupplierControllerUnitTest.java

public class ProductSupplierControllerUnitTest { 

    @Mock 
    private ProductSupplierService productSupplierService; 

    @InjectMocks 
    private ProductSupplierRestController productSupplierRestController; 

    private MockMvc mockMvc; 

    @Before 
    public void setUp() { 
     MockitoAnnotations.initMocks(this); 
     mockMvc = MockMvcBuilders.standaloneSetup(productSupplierRestController) 
       .setControllerAdvice(new ServiceExceptionHandler()).build(); 
    } 

    @Test 
    public void productNotFound() throws Exception { 

     Long incorrectProductId = 2L; 

     Mockito.when(productSupplierService.getProductSuppliers(incorrectProductId, tenantId)) 
       .thenThrow(new EntityNotFoundException(Product.class, String.valueOf(incorrectProductId))); 

     RequestBuilder requestBuilder = MockMvcRequestBuilders.get(prepareRequestUrl(incorrectProductId)) 
       .requestAttr(TENANT_ID, tenantId).contentType(MediaType.APPLICATION_JSON_UTF8); 

     mockMvc.perform(requestBuilder).andExpect(status().isNotFound()) 
       .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8)).andExpect(jsonPath("$.message", 
         is(String.format("Product was not found for parameter(s) %s", incorrectProductId)))); 

     Mockito.verify(productSupplierService, times(1)).getProductSuppliers(incorrectProductId, tenantId); 
     Mockito.verifyNoMoreInteractions(productSupplierService); 
    } 

    @Test 
    public void getProductSuppliersSuccess() throws Exception { 

     Map<String, List<? extends BaseDTO>> result = new HashMap<>(0); 
     ProductSupplierDTO productSupplierDTO = new ProductSupplierDTO(); 
     productSupplierDTO.setSupplierId(correctSupplierId); 
     productSupplierDTO.setBuyPrice(validBuyPrice); 
     productSupplierDTO.setDefaultSupplier(isDefaultSupplier); 

     result.put("product_suppliers", Collections.singletonList(productSupplierDTO)); 

     Mockito.when(productSupplierService.getProductSuppliers(productId, tenantId)).thenReturn(result); 

     RequestBuilder requestBuilder = MockMvcRequestBuilders.get(prepareRequestUrl(productId)) 
       .requestAttr(TENANT_ID, tenantId).contentType(MediaType.APPLICATION_JSON_UTF8); 

     mockMvc.perform(requestBuilder).andExpect(status().isOk()) 
       .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8)) 
       .andExpect(jsonPath("$.product_suppliers", hasSize(1))) 
       .andExpect(jsonPath("$.product_suppliers[0].supplier_id", is(correctSupplierId.intValue()))) 
       .andExpect(jsonPath("$.product_suppliers[0].buy_price", is(validBuyPrice))) 
       .andExpect(jsonPath("$.product_suppliers[0].default_supplier", is(isDefaultSupplier))); 

     Mockito.verify(productSupplierService, times(1)).getProductSuppliers(productId, tenantId); 
     Mockito.verifyNoMoreInteractions(productSupplierService); 
    } 

    // some more tests 
} 

시험은 잘 작동하고 있지만 문제는이 독립 설정이 모든 테스트 케이스 컨트롤러의 방법에 대한 모든 테스트 케이스 전에 완료 URL로 매핑되고 봄 FrameworkServlet가 초기화이다.

이 초기화는 모든 테스트 케이스에 대해 한 번만 수행 할 수 있습니까? 테스트 시간을 줄이기 위해서.

편집 : 코드를 다음과 같이 변경했으며 예상대로 작동합니다. 질문은 그것이 올바른 접근 방법인가?

@RunWith(MockitoJUnitRunner.class) 
public class ProductSupplierControllerUnitTest { 

    @Mock 
    private ProductSupplierService productSupplierService; 

    @InjectMocks 
    private static ProductSupplierRestController productSupplierRestController = new ProductSupplierRestController(); 

    private static MockMvc mockMvc = MockMvcBuilders.standaloneSetup(productSupplierRestController) 
      .setControllerAdvice(new ServiceExceptionHandler()).build(); 

    // tests 
} 

컨트롤러 및 mockMvc를 정적으로 만드는 것이 좋습니까?

답변

0

JUnit을 사용하는 경우 @Before 대신 @BeforeClass 주석을 사용하십시오. 이 어노테이션이있는 메소드는 클래스의 모든 테스트 전에 한 번 호출됩니다.

+0

@BeforeClass를 사용하려면 해당 메소드가 정적이어야하므로 컨트롤러 및 mockmvc 객체도 정적이어야합니다. 나는 그것도 시도했지만 초기화 오류를 제공합니다. – Harshit