mirror of
https://github.com/alibaba/testable-mock.git
synced 2025-03-10 09:40:30 +08:00
split core package into core and processor
This commit is contained in:
parent
419a10669d
commit
989a52a048
@ -8,7 +8,8 @@
|
||||
## 目录结构
|
||||
|
||||
```bash
|
||||
|-- testable-core ➜ 核心组件,提供测试辅助功能、注解和工具类
|
||||
|-- testable-core ➜ 核心组件,提供注解和工具类
|
||||
|-- testable-processor ➜ 编译期代码预处理组件,提供测试辅助功能
|
||||
|-- testable-agent ➜ JavaAgent组件,提供Mock测试相关功能
|
||||
|-- testable-maven-plugin ➜ Maven插件组件,用于简化JavaAgent注入
|
||||
|-- demo
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.testable</groupId>
|
||||
<artifactId>testable-core</artifactId>
|
||||
<artifactId>testable-processor</artifactId>
|
||||
<version>${testable.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
@ -12,4 +12,8 @@ public class BlackBox {
|
||||
return data;
|
||||
}
|
||||
|
||||
public static BlackBox secretBox() {
|
||||
return new BlackBox("secret");
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -47,6 +47,13 @@ public class DemoService {
|
||||
return "anything".trim() + "__" + "anything".substring(1, 2) + "__" + "abc".startsWith("ab");
|
||||
}
|
||||
|
||||
/**
|
||||
* Target 6 - method with static method invoke
|
||||
*/
|
||||
public BlackBox getBox() {
|
||||
return BlackBox.secretBox();
|
||||
}
|
||||
|
||||
public String callerOne() {
|
||||
return callFromDifferentMethod();
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
package com.alibaba.testable.demo;
|
||||
|
||||
import com.alibaba.testable.core.accessor.PrivateAccessor;
|
||||
import com.alibaba.testable.core.annotation.EnablePrivateAccess;
|
||||
import com.alibaba.testable.processor.annotation.EnablePrivateAccess;
|
||||
import com.alibaba.testable.core.annotation.TestableMock;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@ -38,6 +38,11 @@ class DemoServiceTest {
|
||||
return false;
|
||||
}
|
||||
|
||||
@TestableMock
|
||||
private BlackBox secretBox() {
|
||||
return new BlackBox("not_secret_box");
|
||||
}
|
||||
|
||||
@TestableMock
|
||||
private String callFromDifferentMethod(DemoService self) {
|
||||
if (TEST_CASE.equals("should_able_to_get_test_case_name")) {
|
||||
@ -52,13 +57,13 @@ class DemoServiceTest {
|
||||
private DemoService demoService = new DemoService();
|
||||
|
||||
@Test
|
||||
void should_able_to_test_private_method() throws Exception {
|
||||
void should_able_to_mock_private_method() throws Exception {
|
||||
assertEquals("hello - 1", demoService.privateFunc("hello", 1));
|
||||
assertEquals("hello - 1", PrivateAccessor.invoke(demoService, "privateFunc", "hello", 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_able_to_test_private_field() throws Exception {
|
||||
void should_able_to_mock_private_field() throws Exception {
|
||||
demoService.count = 2;
|
||||
assertEquals("4", demoService.privateFieldAccessFunc());
|
||||
PrivateAccessor.set(demoService, "count", 3);
|
||||
@ -67,19 +72,19 @@ class DemoServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_able_to_test_new_object() throws Exception {
|
||||
void should_able_to_mock_new_object() throws Exception {
|
||||
assertEquals("mock_something", demoService.newFunc());
|
||||
verify("createBlackBox").times(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_able_to_test_member_method() throws Exception {
|
||||
void should_able_to_mock_member_method() throws Exception {
|
||||
assertEquals("{ \"res\": \"mock_hello\"}", demoService.outerFunc("hello"));
|
||||
verify("innerFunc").times(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_able_to_test_common_method() throws Exception {
|
||||
void should_able_to_mock_common_method() throws Exception {
|
||||
assertEquals("trim_string__sub_string__false", demoService.commonFunc());
|
||||
verify("trim").times(1);
|
||||
verify("sub").times(1);
|
||||
|
@ -40,7 +40,7 @@
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.testable</groupId>
|
||||
<artifactId>testable-core</artifactId>
|
||||
<artifactId>testable-processor</artifactId>
|
||||
<version>${testable.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
@ -19,4 +19,16 @@ class BlackBox(private val data: String) {
|
||||
return data.startsWith(prefix)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun secretBox(): BlackBox {
|
||||
return BlackBox("secret")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
object ColorBox {
|
||||
fun createBox(color: String): BlackBox {
|
||||
return BlackBox("${color}_Box")
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
package com.alibaba.testable.demo
|
||||
|
||||
import com.alibaba.testable.core.accessor.PrivateAccessor
|
||||
import com.alibaba.testable.core.annotation.EnablePrivateAccess
|
||||
import com.alibaba.testable.processor.annotation.EnablePrivateAccess
|
||||
import com.alibaba.testable.core.annotation.TestableMock
|
||||
import com.alibaba.testable.core.tool.TestableTool.*
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
@ -42,31 +42,31 @@ internal class DemoServiceTest {
|
||||
private val demoService = DemoService()
|
||||
|
||||
@Test
|
||||
fun should_able_to_test_private_method() {
|
||||
fun should_able_to_mock_private_method() {
|
||||
assertEquals("hello - 1", PrivateAccessor.invoke(demoService, "privateFunc", "hello", 1))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun should_able_to_test_private_field() {
|
||||
fun should_able_to_mock_private_field() {
|
||||
PrivateAccessor.set(demoService, "count", 3)
|
||||
assertEquals("5", demoService.privateFieldAccessFunc())
|
||||
assertEquals(5, PrivateAccessor.get(demoService, "count"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun should_able_to_test_new_object() {
|
||||
fun should_able_to_mock_new_object() {
|
||||
assertEquals("mock_something", demoService.newFunc())
|
||||
verify("createBlackBox").times(1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun should_able_to_test_member_method() {
|
||||
fun should_able_to_mock_member_method() {
|
||||
assertEquals("{ \"res\": \"mock_hello\"}", demoService.outerFunc("hello"))
|
||||
verify("innerFunc").times(1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun should_able_to_test_common_method() {
|
||||
fun should_able_to_mock_common_method() {
|
||||
assertEquals("trim_string__sub_string__false", demoService.commonFunc())
|
||||
verify("trim").times(1)
|
||||
verify("sub").times(1)
|
||||
|
@ -3,12 +3,12 @@
|
||||
|
||||
## 引入Testable
|
||||
|
||||
首先在项目`pom.xml`文件中添加`testable-core`依赖:
|
||||
首先在项目`pom.xml`文件中添加`testable-processor`依赖:
|
||||
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>com.alibaba.testable</groupId>
|
||||
<artifactId>testable-core</artifactId>
|
||||
<artifactId>testable-processor</artifactId>
|
||||
<version>${testable.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
@ -51,7 +51,7 @@
|
||||
|
||||
若不希望看到IDE的语法错误提醒,或是在基于JVM的非Java语言项目里(譬如Kotlin语言),也可以借助`PrivateAccessor`工具类来实现私有成员的访问。
|
||||
|
||||
效果见示例项目文件`DemoServiceTest.java`中的`should_able_to_test_private_method()`和`should_able_to_test_private_field()`测试用例。
|
||||
效果见示例项目文件`DemoServiceTest.java`中的`should_able_to_mock_private_method()`和`should_able_to_mock_private_field()`测试用例。
|
||||
|
||||
### Mock被测类的任意方法调用
|
||||
|
||||
@ -63,7 +63,7 @@
|
||||
|
||||
**注意**:当遇到有两个需覆写的方法重名时,可将需覆写的方法名写到`@TestableMock`注解的`targetMethod`参数里,此时Mock方法自身就可以随意命名了。
|
||||
|
||||
示例项目文件`DemoServiceTest.java`中的`should_able_to_test_common_method()`用例详细展示了这种用法。
|
||||
示例项目文件`DemoServiceTest.java`中的`should_able_to_mock_common_method()`用例详细展示了这种用法。
|
||||
|
||||
**【2】覆写被测类自身的成员方法**
|
||||
|
||||
@ -71,7 +71,7 @@
|
||||
|
||||
操作方法与前一种情况相同,Mock方法的第一个参数类型需与被测类相同,即可实现对被测类自身(不论是公有或私有)成员方法的覆写。
|
||||
|
||||
详见示例项目文件`DemoServiceTest.java`中的`should_able_to_test_member_method()`用例。
|
||||
详见示例项目文件`DemoServiceTest.java`中的`should_able_to_mock_member_method()`用例。
|
||||
|
||||
**【3】覆写任意类的new操作**
|
||||
|
||||
@ -79,7 +79,7 @@
|
||||
|
||||
此时被测类中所有用`new`创建指定类的操作(并使用了与Mock方法参数一致的构造函数)将被替换为对该自定义方法的调用。
|
||||
|
||||
详见示例项目文件`DemoServiceTest.java`中的`should_able_to_test_new_object()`用例。
|
||||
详见示例项目文件`DemoServiceTest.java`中的`should_able_to_mock_new_object()`用例。
|
||||
|
||||
**【4】识别当前测试用例和调用来源**
|
||||
|
||||
|
1
pom.xml
1
pom.xml
@ -10,6 +10,7 @@
|
||||
|
||||
<modules>
|
||||
<module>testable-core</module>
|
||||
<module>testable-processor</module>
|
||||
<module>testable-agent</module>
|
||||
<module>testable-maven-plugin</module>
|
||||
<module>demo</module>
|
||||
|
@ -14,6 +14,7 @@
|
||||
<project.compiler.level>1.6</project.compiler.level>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<asm.lib.version>8.0.1</asm.lib.version>
|
||||
<junit.version>5.6.2</junit.version>
|
||||
<testable.version>0.2.1-SNAPSHOT</testable.version>
|
||||
<plugin.compiler.version>3.8.1</plugin.compiler.version>
|
||||
<plugin.jar.version>3.2.0</plugin.jar.version>
|
||||
@ -29,7 +30,7 @@
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<version>5.6.2</version>
|
||||
<version>${junit.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -15,20 +15,14 @@
|
||||
<project.compiler.level>1.6</project.compiler.level>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<plugin.compiler.version>3.8.1</plugin.compiler.version>
|
||||
<junit.version>5.6.2</junit.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>sun.jdk</groupId>
|
||||
<artifactId>tools</artifactId>
|
||||
<version>${java.version}</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${java.home}/../lib/tools.jar</systemPath>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<version>5.6.2</version>
|
||||
<version>${junit.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
@ -43,7 +37,6 @@
|
||||
<source>${project.compiler.level}</source>
|
||||
<target>${project.compiler.level}</target>
|
||||
<encoding>${project.build.sourceEncoding}</encoding>
|
||||
<compilerArgument>-proc:none</compilerArgument>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
@ -1,5 +1,7 @@
|
||||
package com.alibaba.testable.core.annotation;
|
||||
|
||||
import com.alibaba.testable.core.model.MockType;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
@ -12,6 +14,11 @@ import java.lang.annotation.*;
|
||||
@Documented
|
||||
public @interface TestableMock {
|
||||
|
||||
/**
|
||||
* type of mock method
|
||||
*/
|
||||
MockType value() default MockType.MEMBER_METHOD;
|
||||
|
||||
/**
|
||||
* mock specified method instead of method with same name
|
||||
*/
|
||||
|
@ -5,7 +5,6 @@ package com.alibaba.testable.core.constant;
|
||||
*/
|
||||
public final class ConstPool {
|
||||
|
||||
public static final String TESTABLE_PRIVATE_ACCESSOR = "com.alibaba.testable.core.accessor.PrivateAccessor";
|
||||
public static final String TEST_POSTFIX = "Test";
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,14 @@
|
||||
package com.alibaba.testable.core.model;
|
||||
|
||||
/**
|
||||
* Type of mock method
|
||||
*
|
||||
* @author flin
|
||||
*/
|
||||
public enum MockType {
|
||||
|
||||
MEMBER_METHOD,
|
||||
STATIC_METHOD,
|
||||
CONSTRUCTOR
|
||||
|
||||
}
|
@ -36,7 +36,7 @@ public class TypeUtil {
|
||||
/**
|
||||
* type equals
|
||||
*/
|
||||
public static boolean typeEquals(Class<?>[] classesLeft, Class<?>[] classesRight) {
|
||||
private static boolean typeEquals(Class<?>[] classesLeft, Class<?>[] classesRight) {
|
||||
if (classesLeft.length != classesRight.length) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1 +0,0 @@
|
||||
com.alibaba.testable.core.processor.EnablePrivateAccessProcessor
|
59
testable-processor/pom.xml
Normal file
59
testable-processor/pom.xml
Normal file
@ -0,0 +1,59 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<description>Unit test enhancement toolkit</description>
|
||||
<groupId>com.alibaba.testable</groupId>
|
||||
<artifactId>testable-processor</artifactId>
|
||||
<version>0.2.1-SNAPSHOT</version>
|
||||
<name>testable-processor</name>
|
||||
|
||||
<properties>
|
||||
<java.version>1.6</java.version>
|
||||
<project.compiler.level>1.6</project.compiler.level>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<plugin.compiler.version>3.8.1</plugin.compiler.version>
|
||||
<junit.version>5.6.2</junit.version>
|
||||
<testable.version>0.2.1-SNAPSHOT</testable.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.testable</groupId>
|
||||
<artifactId>testable-core</artifactId>
|
||||
<version>${testable.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>sun.jdk</groupId>
|
||||
<artifactId>tools</artifactId>
|
||||
<version>${java.version}</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${java.home}/../lib/tools.jar</systemPath>
|
||||
</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-compiler-plugin</artifactId>
|
||||
<version>${plugin.compiler.version}</version>
|
||||
<configuration>
|
||||
<source>${project.compiler.level}</source>
|
||||
<target>${project.compiler.level}</target>
|
||||
<encoding>${project.build.sourceEncoding}</encoding>
|
||||
<compilerArgument>-proc:none</compilerArgument>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
@ -1,10 +1,10 @@
|
||||
package com.alibaba.testable.core.processor;
|
||||
package com.alibaba.testable.processor;
|
||||
|
||||
import com.alibaba.testable.core.annotation.EnablePrivateAccess;
|
||||
import com.alibaba.testable.core.constant.ConstPool;
|
||||
import com.alibaba.testable.core.model.TestableContext;
|
||||
import com.alibaba.testable.core.translator.EnablePrivateAccessTranslator;
|
||||
import com.alibaba.testable.core.util.TestableLogger;
|
||||
import com.alibaba.testable.processor.annotation.EnablePrivateAccess;
|
||||
import com.alibaba.testable.processor.constant.ConstPool;
|
||||
import com.alibaba.testable.processor.model.TestableContext;
|
||||
import com.alibaba.testable.processor.translator.EnablePrivateAccessTranslator;
|
||||
import com.alibaba.testable.processor.util.TestableLogger;
|
||||
import com.sun.tools.javac.api.JavacTrees;
|
||||
import com.sun.tools.javac.code.Symbol;
|
||||
import com.sun.tools.javac.processing.JavacProcessingEnvironment;
|
||||
@ -26,7 +26,7 @@ import java.util.Set;
|
||||
/**
|
||||
* @author flin
|
||||
*/
|
||||
@SupportedAnnotationTypes("com.alibaba.testable.core.annotation.EnablePrivateAccess")
|
||||
@SupportedAnnotationTypes("com.alibaba.testable.processor.annotation.EnablePrivateAccess")
|
||||
public class EnablePrivateAccessProcessor extends AbstractProcessor {
|
||||
|
||||
private TestableContext cx;
|
@ -1,4 +1,4 @@
|
||||
package com.alibaba.testable.core.annotation;
|
||||
package com.alibaba.testable.processor.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
@ -0,0 +1,11 @@
|
||||
package com.alibaba.testable.processor.constant;
|
||||
|
||||
/**
|
||||
* @author flin
|
||||
*/
|
||||
public final class ConstPool {
|
||||
|
||||
public static final String TESTABLE_PRIVATE_ACCESSOR = "com.alibaba.testable.core.accessor.PrivateAccessor";
|
||||
public static final String TEST_POSTFIX = "Test";
|
||||
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
package com.alibaba.testable.core.generator;
|
||||
package com.alibaba.testable.processor.generator;
|
||||
|
||||
import com.alibaba.testable.core.model.TestableContext;
|
||||
import com.alibaba.testable.processor.model.TestableContext;
|
||||
import com.sun.tools.javac.tree.JCTree.*;
|
||||
|
||||
/**
|
@ -1,7 +1,7 @@
|
||||
package com.alibaba.testable.core.generator;
|
||||
package com.alibaba.testable.processor.generator;
|
||||
|
||||
import com.alibaba.testable.core.model.TestableContext;
|
||||
import com.alibaba.testable.core.constant.ConstPool;
|
||||
import com.alibaba.testable.processor.model.TestableContext;
|
||||
import com.alibaba.testable.processor.constant.ConstPool;
|
||||
import com.sun.tools.javac.tree.JCTree.*;
|
||||
import com.sun.tools.javac.util.List;
|
||||
import com.sun.tools.javac.util.ListBuffer;
|
@ -1,6 +1,6 @@
|
||||
package com.alibaba.testable.core.model;
|
||||
package com.alibaba.testable.processor.model;
|
||||
|
||||
import com.alibaba.testable.core.util.TestableLogger;
|
||||
import com.alibaba.testable.processor.util.TestableLogger;
|
||||
import com.sun.tools.javac.api.JavacTrees;
|
||||
import com.sun.tools.javac.tree.TreeMaker;
|
||||
import com.sun.tools.javac.util.Names;
|
@ -1,4 +1,4 @@
|
||||
package com.alibaba.testable.core.translator;
|
||||
package com.alibaba.testable.processor.translator;
|
||||
|
||||
import com.sun.tools.javac.tree.JCTree.*;
|
||||
import com.sun.tools.javac.tree.TreeTranslator;
|
@ -1,8 +1,8 @@
|
||||
package com.alibaba.testable.core.translator;
|
||||
package com.alibaba.testable.processor.translator;
|
||||
|
||||
import com.alibaba.testable.core.constant.ConstPool;
|
||||
import com.alibaba.testable.core.generator.PrivateAccessStatementGenerator;
|
||||
import com.alibaba.testable.core.model.TestableContext;
|
||||
import com.alibaba.testable.processor.constant.ConstPool;
|
||||
import com.alibaba.testable.processor.generator.PrivateAccessStatementGenerator;
|
||||
import com.alibaba.testable.processor.model.TestableContext;
|
||||
import com.sun.tools.javac.tree.JCTree.*;
|
||||
import com.sun.tools.javac.util.ListBuffer;
|
||||
import com.sun.tools.javac.util.Name;
|
@ -1,4 +1,4 @@
|
||||
package com.alibaba.testable.core.util;
|
||||
package com.alibaba.testable.processor.util;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.alibaba.testable.core.util;
|
||||
package com.alibaba.testable.processor.util;
|
||||
|
||||
import javax.annotation.processing.Messager;
|
||||
import javax.tools.Diagnostic;
|
@ -0,0 +1 @@
|
||||
com.alibaba.testable.processor.EnablePrivateAccessProcessor
|
@ -1,4 +1,4 @@
|
||||
package com.alibaba.testable.core.util;
|
||||
package com.alibaba.testable.processor.util;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
Loading…
Reference in New Issue
Block a user