testable-mock/docs/Usage.md
2020-10-23 23:23:58 +08:00

3.9 KiB
Raw Blame History

使用说明

引入Testable

首先在项目pom.xml文件中添加testable-core依赖:

<dependency>
    <groupId>com.alibaba.testable</groupId>
    <artifactId>testable-core</artifactId>
    <version>${testable.version}</version>
    <scope>provided</scope>
</dependency>

此时项目就获得了在单元测试中随意访问被测类私有字段和方法的能力(需配合注解使用,见下文详述)。

若要开启极速Mock功能还需在pom.xml里加上testable-maven-plugin插件。

<plugin>
    <groupId>com.alibaba.testable</groupId>
    <artifactId>testable-maven-plugin</artifactId>
    <version>${testable.version}</version>
    <executions>
        <execution>
            <id>prepare</id>
            <goals>
                <goal>prepare</goal>
            </goals>
        </execution>
    </executions>
</plugin>

使用Testable

Testable目前能为测试类提供两项增强能力:直接访问被测类的私有成员极速Mock被测方法中的调用

访问私有成员字段和方法

在测试类上添加@EnableTestable注解然后即可直接在单元测试里像访问公有成员一样调用被测类的私有方法、读写私有成员变量了虽然IDE可能会提升语法有误但编译器将会正常运行测试。

若不希望看到IDE的语法错误提醒或是在基于JVM的非Java语言项目里譬如Kotlin语言也可以借助PrivateAccessor工具类来实现私有成员的访问。

效果见示例项目文件DemoServiceTest.java中的should_able_to_test_private_method()should_able_to_test_private_field()测试用例。

Mock被测类的任意方法调用

【1】覆写任意类的方法调用

定义一个普通方法,使它与待覆写方法名称和返回值类型完全一致,仅比待覆写方法在首位多一个该方法所属对象类型的参数,然后为这个方法加上@TestableInject注解,并设置targetClass属性值为被Mock方法的所属类型。

此时被测类中所有对该类指定方法的调用将在单元测试运行时自动被替换为对上述自定义Mock方法的调用。

@TestableInject注解还有一个很少需要用到的targetMethod属性用于指定Mock的目标方法名称。使用此参数后被注释修饰的方法名称就可以随意命名了通常仅在遇到极其罕见的Mock方法签名重名情况时才需要使用。

示例项目文件DemoServiceTest.java中的should_able_to_test_common_method()用例详细展示了这几种用法。

【2】覆写任意类的new操作

同样还是定义一个普通方法,然后加上@TestableInject注解。方法名称随意只需让方法的返回值为要覆写new操作的目标类型且参数与指定类构造方法完全一致。

此时被测类中所有用new创建指定类的操作将被替换为对该自定义方法的调用。

详见示例项目文件DemoServiceTest.java中的should_able_to_test_new_object()用例。

【3】覆写被测类自身的私有成员方法

有时候被测类自身的某个成员方法访问了外部系统在进行单元测试的时候就需要将这个备查样自己的成员方法Mock掉。

在测试类中声明一个名称、参数和返回值类型都与要覆写的目标方法完全一致的普通方法,同样加上@TestableInject注解,不配置targetClass属性,即可实现对被测类私有成员方法的覆写。

详见示例项目文件DemoServiceTest.java中的should_able_to_test_member_method()用例。

【4】识别当前测试用例和调用来源

在Mock方法中可以通过TestableTool.TEST_CASETestableTool.SOURCE_METHOD来识别当前运行的测试用例名称进入该Mock方法前的被测类方法名称,从而区分处理不同的调用场景。

详见示例项目文件DemoServiceTest.java中的should_able_to_get_source_method_name()should_able_to_get_test_case_name()用例。