[笔记] Java 测试的一些注解

@InjectMocks
模拟一个对象,该对象内部的其他对象可以被 @Mock 注入,没有被注入的对象被设置为 null


@Mock
模拟一个对象,该对象内部的其他对象被设置为 null


@MockBean
这个是 SpringBoot 的注解,和 @Mock 类似,但会替代 SpringBoot 的 Bean,比如 @Autowired 指定的 Bean 就会被这个模拟对象替换


@RunWith(SpringRunner.class)
替换默认的 Runner,比如使用 Spring 的 runner,另外 SpringJUnit4ClassRunner 和 SpringRunner 是一样的


@SpringBootTest
创建 spring boot application context,会初始化定义的 Bean,比如 @Autowired 对象 ,比如 @Value 导入的配置,会导致程序启动慢,做的事比较多


@DirtiesContext
在测试的类或方法的前后,清理 application context,默认是 after class 清理,可以防止不同测试之间互相干扰


@ActiveProfiles("test")
指定配置文件为 application-test.yml


@WebAppConfiguration
加载 web application context 通常用于 controller 的测试


@AutoConfigureMockMvc
自动配置 MockMvc 的单元测试,用于 MVC 测试

    @Autowired
    private MockMvc mvc;

    @Test
    public void test() throws Exception{
        MvcResult mvcResult = mvc
                .perform(MockMvcRequestBuilders
                        .post(url)
                        .contentType(MediaType.APPLICATION_JSON_UTF8)
                        .content(body))
                .andDo(MockMvcResultHandlers.print())
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andReturn();
    }

用于发送和验证 http 请求


WireMockRule : 模拟外部 server

        <dependency>
            <groupId>com.github.tomakehurst</groupId>
            <artifactId>wiremock-standalone</artifactId>
            <version>${version.wiremock}</version>
            <scope>test</scope>
        </dependency>



import com.github.tomakehurst.wiremock.client.WireMock;
import com.github.tomakehurst.wiremock.common.ConsoleNotifier;
import com.github.tomakehurst.wiremock.junit.WireMockRule;

import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.containing;
import static com.github.tomakehurst.wiremock.client.WireMock.post;
import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlPathMatching;



    @ClassRule
    public static WireMockRule serverSimulator = new WireMockRule(wireMockConfig()
            .port(9000).notifier(new ConsoleNotifier(false)));


    @Test
    public void test() throws Exception {
        // 重置
        serverSimulator.resetRequests();

        // 配置 server 要接收的请求和返回的内容
        serverSimulator.stubFor(
                post(urlPathMatching(url))
                        .willReturn(aResponse()
                                .withStatus(200)
                                .withHeader("Content-Type", "application/json")
                                .withBody(response)));

        // 执行测试代码

        // 验证 server 收到的请求
        serverSimulator.verify(invokedTimes,
                postRequestedFor(urlPathMatching(url))
                        .withHeader("Authorization", WireMock.matching(auth))
                        .withRequestBody(containing(request)));
    }

这样避免了自己再编写运行模拟 server 的程序


PowerMockito

有些函数 Mockito 无法处理,比如 static,final(不能被子类覆盖的函数),native(其他语言实现的函数),constructor

PowerMockito 可以 mock 这些函数

// @PrepareForTest 指定需要用 PowerMockito 进行 mock 的类,可以注解在测试类,也可以注解在测试函数
// @RunWith(PowerMockRunner.class) 的测试类依然可以使用 Mockito
// @PowerMockIgnore 注解的包不会被 PowerMockito 的类加载器加载,而是被系统的类加载器加载,主要是一些和 xml 交互的类容易出 classloader 错误
// @SuppressStaticInitializationFor 不要执行静态代码
@RunWith(PowerMockRunner.class)
@PrepareForTest({ClassA.class, ClassB.class})
@PowerMockIgnore({"org.apache.logging.log4j.*", "com.sun.org.apache.xerces.*"})
@SuppressStaticInitializationFor("com.xxx.xxx.ClassA")


    // PowerMockito.mock 创建的可以 mock 静态/final/constructor 等函数
    ClassA class = PowerMockito.mock(ClassA.class);

    // PowerMockito.when 其实是直接调 Mockito.when,所以用 Mockito.when 也可以
    PowerMockito.when(class.get(any(), any())).thenReturn("");

    PowerMockito.whenNew(ClassA.class).withNoArguments().thenReturn(obj);

    PowerMockito.mockStatic(ClassA.class);
    PowerMockito.when(ClassA.staticMethod()).thenAnswer(
            invocationOnMock -> {
                System.out.println("test");
                return null;
            }
    );

    // 如果是 void 函数,应该用另外一种方式
    doNothing().when(mockObject).mockMethod(any());
    doAnswer(answer).when(mockObject).mockMethod(any());

PowerMockito 可以和 Mockito 一起用


@WebMvcTest
@WebFluxTest
@DataJpaTest
@DataJdbcTest



posted @ 2021-07-28 01:22  moon~light  阅读(381)  评论(0编辑  收藏  举报