zoukankan      html  css  js  c++  java
  • [笔记] 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



  • 相关阅读:
    Python购物车的实现课程
    第一天作业二 三级菜单的实现
    windows快捷键命令汇总整理
    python课程第一天作业1-模拟登录
    Java中的代理
    Java中的继承
    Java中的访问权限细谈
    Java中的参数列表
    Java中的this关键字老生常谈
    数据结构与算法Java描述 队列
  • 原文地址:https://www.cnblogs.com/moonlight-lin/p/15068620.html
Copyright © 2011-2022 走看看