将MockMvc用于Junit参数化测试

yshpjwxd  于 2023-10-20  发布在  其他
关注(0)|答案(1)|浏览(131)

我需要用这么多的测试用例来测试API。正因为如此,我欺骗使用Junit参数化测试。
但是我不能运行我的测试,因为MockMvc不能自动运行,并且它是null。
这是我的测试类:

@RunWith(Parameterized.class)
@AutoConfigureMockMvc
@SpringBootTest
public class BadgeControllerIT {

    @Resource
    private MockMvc mockMvc;

    private final MultiValueMap<String, String> params;

    private final String expectedBadgeAsSVG;

    private final ResultMatcher status;

    public BadgeControllerIT(final MultiValueMap<String, String> params,
                             final String expectedBadgeAsSVG,
                             final ResultMatcher status) {
        this.params = params;
        this.expectedBadgeAsSVG = expectedBadgeAsSVG;
        this.status = status;
    }

    @Parameterized.Parameters
    public static Collection<Object[]> parameters() {
        return Arrays.asList(BadgeControllerTestsInputProvider.TEST_INPUTS);
    }

    @Test
    public void badgeControllerTests() throws Exception {
        mockMvc
            .perform(
                get("/api/badge")
                    .queryParams(params)
                    .accept("image/svg+xml")
            )
            .andExpect(status)
            .andExpect(content().string(expectedBadgeAsSVG));
    }
}

在这堂课上我写了我的测试用例:

public class BadgeControllerTestsInputProvider {

    public final static Object[][] TEST_INPUTS = new Object[][]{
        {
            new LinkedMultiValueMap<String, String>(),
            readBadge("some-badge"),
            status().isOk()
        }
    };

    private static String readBadge(String badge) {
        try {
             final File svgFile = ResourceUtils.getFile("classpath:testdata/" + badge + ".svg");
             return FileUtils.readFileToString(svgFile, StandardCharsets.UTF_8);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

当我尝试运行测试时,我遇到了这个异常:

java.lang.NullPointerException: Cannot invoke "org.springframework.test.web.servlet.MockMvc.perform(org.springframework.test.web.servlet.RequestBuilder)" because "this.mockMvc" is null

我也试着自己示例化MockMvc,但我得到了异常:

@RunWith(Parameterized.class)
@WebAppConfiguration
@SpringBootTest
public class BadgeControllerIT {

    @Resource
    private WebApplicationContext webApplicationContext;

    private MockMvc mockMvc;

    @Before
    public void setup() {
        this.mockMvc = MockMvcBuilders.webAppContextSetup(this.webApplicationContext).build();
    }

    .
    .
    .

例外情况:

java.lang.IllegalArgumentException: WebApplicationContext is required

    at org.springframework.util.Assert.notNull(Assert.java:201)
    at org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder.<init>(DefaultMockMvcBuilder.java:52)
    at org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup(MockMvcBuilders.java:51)
iibxawm4

iibxawm41#

正如M. Deinum在评论中建议的那样,问题在于使用JUnit4而不是JUnit5。
所以我决定发布一个答案与解决这个问题的任何人有同样的问题。
这是我的测试类现在的样子:

@AutoConfigureMockMvc
@SpringBootTest
public class BadgeControllerIT {

    @Resource
    private MockMvc mockMvc;

    @ParameterizedTest
    @ArgumentsSource(BadgeControllerTestsArgumentProvider.class)
    public void badgeControllerTests(MultiValueMap<String, String> params, String expectedBadgeAsSVG, ResultMatcher status) throws Exception {
        mockMvc
            .perform(
                get("/api/badge")
                    .queryParams(params)
                    .accept("image/svg+xml")
            )
            .andExpect(status)
            .andExpect(content().string(expectedBadgeAsSVG));
    }
}

以及测试用例提供程序类:

public class BadgeControllerTestsArgumentProvider implements ArgumentsProvider {

    @Override
    public Stream<? extends Arguments> provideArguments(ExtensionContext extensionContext) {
        return Stream.of(
            Arguments.of(
                new LinkedMultiValueMap<String, String>(),
                readBadge("1"),
                status().isOk()
            )
        );
    }

    private static String readBadge(String badge) {
        try {
            final File svgFile = ResourceUtils.getFile("classpath:testdata/" + badge + ".svg");
            return FileUtils.readFileToString(svgFile, StandardCharsets.UTF_8);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

相关问题