如何在Spring Boot中的所有测试用例之前只设置一次独立控制器?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在Spring Boot中的所有测试用例之前只设置一次独立控制器?相关的知识,希望对你有一定的参考价值。

我正在为控制器编写单元测试。我正在模拟服务层并使用独立设置用于休息控制器。

product supplier controller unit test.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并初始化了Spring 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静态化是一种好习惯吗?

答案

如果使用JUnit,则使用注释@BeforeClass而不是@Before。具有此批注的方法将在类中的所有测试之前调用一次。

以上是关于如何在Spring Boot中的所有测试用例之前只设置一次独立控制器?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Spring Boot 应用程序中为带有 @Configuration 注释的类编写单元测试用例

在 Spring Boot 中,如何在每次测试之前重置指标注册表?

在Spring Boot Junit测试用例中使用contextLoads方法有什么用?

Spring Boot:如何为删除其余模板编写单元测试用例

Spring Boot:在单元测试中用一个覆盖多个bean

Spring Boot 编写Test测试用例的几种方式