java alibaba.teastable 测试入门

本文档介绍了如何使用阿里巴巴的Testable框架进行单元测试,包括pom配置、创建mock环境、编写测试逻辑和验证返回值或副作用。Testable框架允许在同一个包内创建测试类,通过模拟方法实现对被测试类的控制。测试逻辑主要涉及修改外部参数和校验方法调用的影响。此外,还展示了如何测试方法的返回值和验证方法执行后的状态变化。
摘要由CSDN通过智能技术生成

官方文档传送门

1. pom 配置

	<properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <junit.version>5.6.2</junit.version>
        <testable.version>0.6.10</testable.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>com.alibaba.testable</groupId>
            <artifactId>testable-all</artifactId>
            <version>${testable.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.0.0-M5</version>
                <configuration>
                    <argLine>@{argLine} -javaagent:${settings.localRepository}/com/alibaba/testable/testable-agent/${testable.version}/testable-agent-${testable.version}.jar</argLine>
                </configuration>
            </plugin>
		</plugins>
	</build>

2. mock环境

测试类和被测试类一定要在同一个包下,并且类名一定是<被测试类>Test
如被测试类是 src/main/java/com.alibaba.demo.basic.DemoInherit
那么测试类应该是 src/test/java/com.alibaba.demo.basic.DemoInheritTest
否则mock的方法将无法生效

在被测试类中写一个静态内部类Mock,将需要mock的方法放在Mock中,如下:

class DemoInheritTest {

    private DemoInherit demoInherit = new DemoInherit();

    public static class Mock {
    	@MockInvoke(targetMethod = "put")
        private void put_into_box(Box self, String something) {
            self.put("put_" + something + "_into_box");
        }

        @MockInvoke(targetMethod = "put")
        private void put_into_blackbox(BlackBox self, String something) {
            self.put("put_" + something + "_into_blackbox");
        }

        @MockInvoke(targetMethod = "get")
        private String get_from_box(Box self) {
            return "get_from_box";
        }
        // 要覆写的构造函数签名为`BlackBox(String)`
		// Mock方法返回`BlackBox`类型对象,方法的名称随意起
		@MockContructor
		private BlackBox createBlackBox(String text) {
		    return new BlackBox("mock_" + text);
		}
    }
}
  • 实际规则约定归纳起来只有两条:
    Mock非构造方法,拷贝原方法定义到Mock容器类,加@MockMethod注解
    Mock构造方法,拷贝原方法定义到Mock容器类,返回值换成构造的类型,方法名随意,加@MockContructor注解
  • 如果需要修改成员变量
    直接使用 PrivateAccessor.set

3. 写测试逻辑

测试逻辑比较简单,修改方法内部使用到的外部参数,或者修改方法调用值,调用被测方法,校验方法副作用

	@Test
    public void testTimeRange() {
    	// 调用私有方法
        UserDTO t = PrivateAccessor.invoke(userService, "syncFromPdd", "1068", "123", new PopShop(), 1);
        // 调用 非私有方法
        BlackBox box = (BlackBox)demoInherit.putIntoBox();
    }

4. 校验返回值或者“副作用”

不返回任何值也不产生任何"副作用"的方法没有存在的意义

  • 测试返回值

    @Test
    void should_mock_call_sub_object_method_by_sub_object() {
        BlackBox box = demoInherit.putIntoBlackBox();
        assertEquals("put_data_into_blackbox", box.get());
    }
  • 校验副作用
    • 修改外部变量
    • 调用外部方法
	@Test
    public void testSaveToCache() {
        Integer firstVal = demo.initHash("hello"); // 访问私有方法
        Integer nextVal = demo.nextHash(firstVal, "hello"); // 访问私有方法
        // 调用无返回值方法
        demo.saveToCache("demo", "hello");
        // 读取私有变量校验副作用
        assertEquals(firstVal, demo.hashCache.get("demo::hello")); // 读取私有变量
        demo.saveToCache("demo", "hello");
        assertEquals(nextVal, demo.hashCache.get("demo::hello")); // 读取私有变量
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值