当前位置: 首页 > 知识库问答 >
问题:

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

虞修平
2023-03-14

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

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和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设置为静态是一种好做法吗?

共有1个答案

韩捷
2023-03-14

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

 类似资料:
  • 在spring boot中@RequestBody内容到达控制器之前,我如何覆盖它? > 此外,我还搜索了Request estBodyAdviceAdapter。 有几个链接对spring boot不起作用。 如何多次读取request.getInputStream() 如何在Spring引导到达控制器之前修改请求正文 现在,我可以将输入流读入字符串中,进行一些修改并设置回控制器的输入流吗?

  • 因此,我正在进行我的第一个Spring Boot项目,我一直在进行测试。我查了很多例子,但似乎都不管用。 这是我的控制器的当前测试: 这是可行的,但在sonarqube上,我发现我的代码覆盖率为0%,而我似乎找不到一个测试,它的覆盖率甚至超过了零。有谁能给我一个关于如何为控制器编写一个好的单元测试的例子,然后我就可以根据您的例子自己解决这个问题。 这是我的控制器: 这是我的服务(以防您需要): 还

  • 问题内容: 您是否建议在@Test方法中对测试用例进行任何分组,还是每个测试方案都有一个@Test方法?例如,假设有多种方法可以在应用程序中设置上下文。 以下想法可以接受吗? 或者,您宁愿建议这样做,让每个方法都尽可能原子化: 对于任何反馈,我们都表示感谢。 问题答案: 我更喜欢每种方法有一个测试用例。 首先,如果将它们拆分为多个方法,则比查找代码中嵌入的注释要容易得多。大多数IDE都会为您提供方

  • 我有使用Selenium独立服务器运行的PHPUnit端到端测试。我的测试扩展了PHPUnit_Extensions_Selenium2TestCase,我使用$this设置浏览器- 谢谢

  • 我的SpringBoot应用程序中有一个控制器: 我想在mocks的帮助下,将其与服务分开进行测试。如何实施?