diff --git a/demo/java-demo/src/main/java/com/alibaba/testable/demo/BlackBox.java b/demo/java-demo/src/main/java/com/alibaba/testable/demo/model/BlackBox.java
similarity index 89%
rename from demo/java-demo/src/main/java/com/alibaba/testable/demo/BlackBox.java
rename to demo/java-demo/src/main/java/com/alibaba/testable/demo/model/BlackBox.java
index 7201ed0..699a09c 100644
--- a/demo/java-demo/src/main/java/com/alibaba/testable/demo/BlackBox.java
+++ b/demo/java-demo/src/main/java/com/alibaba/testable/demo/model/BlackBox.java
@@ -1,4 +1,4 @@
-package com.alibaba.testable.demo;
+package com.alibaba.testable.demo.model;
public class BlackBox implements Box {
diff --git a/demo/java-demo/src/main/java/com/alibaba/testable/demo/Box.java b/demo/java-demo/src/main/java/com/alibaba/testable/demo/model/Box.java
similarity index 59%
rename from demo/java-demo/src/main/java/com/alibaba/testable/demo/Box.java
rename to demo/java-demo/src/main/java/com/alibaba/testable/demo/model/Box.java
index 78d5735..2778e72 100644
--- a/demo/java-demo/src/main/java/com/alibaba/testable/demo/Box.java
+++ b/demo/java-demo/src/main/java/com/alibaba/testable/demo/model/Box.java
@@ -1,4 +1,4 @@
-package com.alibaba.testable.demo;
+package com.alibaba.testable.demo.model;
public interface Box {
diff --git a/demo/java-demo/src/main/java/com/alibaba/testable/demo/DemoService.java b/demo/java-demo/src/main/java/com/alibaba/testable/demo/service/DemoMockService.java
similarity index 62%
rename from demo/java-demo/src/main/java/com/alibaba/testable/demo/DemoService.java
rename to demo/java-demo/src/main/java/com/alibaba/testable/demo/service/DemoMockService.java
index 49efa0f..f7a619f 100644
--- a/demo/java-demo/src/main/java/com/alibaba/testable/demo/DemoService.java
+++ b/demo/java-demo/src/main/java/com/alibaba/testable/demo/service/DemoMockService.java
@@ -1,32 +1,17 @@
-package com.alibaba.testable.demo;
+package com.alibaba.testable.demo.service;
+import com.alibaba.testable.demo.model.BlackBox;
+import com.alibaba.testable.demo.model.Box;
import org.springframework.stereotype.Service;
import sun.net.www.http.HttpClient;
import java.net.URL;
@Service
-public class DemoService {
-
- private int count;
+public class DemoMockService {
/**
- * Target 1 - private method
- */
- private String privateFunc(String s, int i) {
- return s + " - " + i;
- }
-
- /**
- * Target 2 - method with private field access
- */
- public String privateFieldAccessFunc() {
- count += 2;
- return String.valueOf(count);
- }
-
- /**
- * Target 3 - method with new operation
+ * method with new operation
*/
public String newFunc() {
BlackBox component = new BlackBox("something");
@@ -34,28 +19,28 @@ public class DemoService {
}
/**
- * Target 4 - method with member method invoke
+ * method with member method invoke
*/
public String outerFunc(String s) throws Exception {
return "{ \"res\": \"" + innerFunc(s) + "\"}";
}
/**
- * Target 5 - method with common method invoke
+ * method with common method invoke
*/
public String commonFunc() {
return "anything".trim() + "__" + "anything".substring(1, 2) + "__" + "abc".startsWith("ab");
}
/**
- * Target 6 - method with static method invoke
+ * method with static method invoke
*/
public BlackBox getBox() {
return BlackBox.secretBox();
}
/**
- * Target 7 - method with override method invoke
+ * method with override method invoke
*/
public Box putBox() {
Box box = new BlackBox("");
@@ -64,7 +49,7 @@ public class DemoService {
}
/**
- * Target 8 - two methods invoke same private method
+ * two methods invoke same private method
*/
public String callerOne() {
return callFromDifferentMethod();
diff --git a/demo/java-demo/src/main/java/com/alibaba/testable/demo/service/DemoPrivateAccessService.java b/demo/java-demo/src/main/java/com/alibaba/testable/demo/service/DemoPrivateAccessService.java
new file mode 100644
index 0000000..fdd2f2d
--- /dev/null
+++ b/demo/java-demo/src/main/java/com/alibaba/testable/demo/service/DemoPrivateAccessService.java
@@ -0,0 +1,25 @@
+package com.alibaba.testable.demo.service;
+
+import org.springframework.stereotype.Service;
+
+@Service
+public class DemoPrivateAccessService {
+
+ private int count;
+
+ /**
+ * private method
+ */
+ private String privateFunc(String s, int i) {
+ return s + " - " + i;
+ }
+
+ /**
+ * method with private field access
+ */
+ public String privateFieldAccessFunc() {
+ count += 2;
+ return String.valueOf(count);
+ }
+
+}
diff --git a/demo/java-demo/src/test/java/com/alibaba/testable/demo/DemoServiceTest.java b/demo/java-demo/src/test/java/com/alibaba/testable/demo/service/DemoMockServiceTest.java
similarity index 74%
rename from demo/java-demo/src/test/java/com/alibaba/testable/demo/DemoServiceTest.java
rename to demo/java-demo/src/test/java/com/alibaba/testable/demo/service/DemoMockServiceTest.java
index 6a63f58..f752b9f 100644
--- a/demo/java-demo/src/test/java/com/alibaba/testable/demo/DemoServiceTest.java
+++ b/demo/java-demo/src/test/java/com/alibaba/testable/demo/service/DemoMockServiceTest.java
@@ -1,8 +1,8 @@
-package com.alibaba.testable.demo;
+package com.alibaba.testable.demo.service;
-import com.alibaba.testable.core.accessor.PrivateAccessor;
-import com.alibaba.testable.processor.annotation.EnablePrivateAccess;
import com.alibaba.testable.core.annotation.TestableMock;
+import com.alibaba.testable.demo.model.BlackBox;
+import com.alibaba.testable.demo.model.Box;
import org.junit.jupiter.api.Test;
import java.util.concurrent.Executors;
@@ -10,8 +10,7 @@ import java.util.concurrent.Executors;
import static com.alibaba.testable.core.tool.TestableTool.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
-@EnablePrivateAccess
-class DemoServiceTest {
+class DemoMockServiceTest {
@TestableMock(targetMethod = CONSTRUCTOR)
private BlackBox createBlackBox(String text) {
@@ -19,7 +18,7 @@ class DemoServiceTest {
}
@TestableMock
- private String innerFunc(DemoService self, String text) {
+ private String innerFunc(DemoMockService self, String text) {
return "mock_" + text;
}
@@ -39,7 +38,7 @@ class DemoServiceTest {
}
@TestableMock
- private BlackBox secretBox(BlackBox _) {
+ private BlackBox secretBox(BlackBox ignore) {
return new BlackBox("not_secret_box");
}
@@ -49,7 +48,7 @@ class DemoServiceTest {
}
@TestableMock
- private String callFromDifferentMethod(DemoService self) {
+ private String callFromDifferentMethod(DemoMockService self) {
if (TEST_CASE.equals("should_able_to_get_test_case_name")) {
return "mock_special";
}
@@ -59,22 +58,7 @@ class DemoServiceTest {
}
}
- private DemoService demoService = new DemoService();
-
- @Test
- 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_mock_private_field() throws Exception {
- demoService.count = 2;
- assertEquals("4", demoService.privateFieldAccessFunc());
- PrivateAccessor.set(demoService, "count", 3);
- assertEquals("5", demoService.privateFieldAccessFunc());
- assertEquals(new Integer(5), PrivateAccessor.get(demoService, "count"));
- }
+ private DemoMockService demoService = new DemoMockService();
@Test
void should_able_to_mock_new_object() throws Exception {
diff --git a/demo/java-demo/src/test/java/com/alibaba/testable/demo/service/DemoPrivateAccessServiceTest.java b/demo/java-demo/src/test/java/com/alibaba/testable/demo/service/DemoPrivateAccessServiceTest.java
new file mode 100644
index 0000000..0bb3d7f
--- /dev/null
+++ b/demo/java-demo/src/test/java/com/alibaba/testable/demo/service/DemoPrivateAccessServiceTest.java
@@ -0,0 +1,29 @@
+package com.alibaba.testable.demo.service;
+
+import com.alibaba.testable.core.accessor.PrivateAccessor;
+import com.alibaba.testable.processor.annotation.EnablePrivateAccess;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+@EnablePrivateAccess
+class DemoPrivateAccessServiceTest {
+
+ private DemoPrivateAccessService demoService = new DemoPrivateAccessService();
+
+ @Test
+ 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_mock_private_field() throws Exception {
+ demoService.count = 2;
+ assertEquals("4", demoService.privateFieldAccessFunc());
+ PrivateAccessor.set(demoService, "count", 3);
+ assertEquals("5", demoService.privateFieldAccessFunc());
+ assertEquals(new Integer(5), PrivateAccessor.get(demoService, "count"));
+ }
+
+}
diff --git a/demo/kotlin-demo/src/main/kotlin/com/alibaba/testable/demo/BlackBox.kt b/demo/kotlin-demo/src/main/kotlin/com/alibaba/testable/demo/model/BlackBox.kt
similarity index 94%
rename from demo/kotlin-demo/src/main/kotlin/com/alibaba/testable/demo/BlackBox.kt
rename to demo/kotlin-demo/src/main/kotlin/com/alibaba/testable/demo/model/BlackBox.kt
index 1b9af24..e6be1be 100644
--- a/demo/kotlin-demo/src/main/kotlin/com/alibaba/testable/demo/BlackBox.kt
+++ b/demo/kotlin-demo/src/main/kotlin/com/alibaba/testable/demo/model/BlackBox.kt
@@ -1,4 +1,4 @@
-package com.alibaba.testable.demo
+package com.alibaba.testable.demo.model
class BlackBox(private var data: String) : Box {
diff --git a/demo/kotlin-demo/src/main/kotlin/com/alibaba/testable/demo/Box.kt b/demo/kotlin-demo/src/main/kotlin/com/alibaba/testable/demo/model/Box.kt
similarity index 56%
rename from demo/kotlin-demo/src/main/kotlin/com/alibaba/testable/demo/Box.kt
rename to demo/kotlin-demo/src/main/kotlin/com/alibaba/testable/demo/model/Box.kt
index 241e73b..d88da88 100644
--- a/demo/kotlin-demo/src/main/kotlin/com/alibaba/testable/demo/Box.kt
+++ b/demo/kotlin-demo/src/main/kotlin/com/alibaba/testable/demo/model/Box.kt
@@ -1,4 +1,4 @@
-package com.alibaba.testable.demo
+package com.alibaba.testable.demo.model
interface Box {
diff --git a/demo/kotlin-demo/src/main/kotlin/com/alibaba/testable/demo/DemoService.kt b/demo/kotlin-demo/src/main/kotlin/com/alibaba/testable/demo/service/DemoMockService.kt
similarity index 60%
rename from demo/kotlin-demo/src/main/kotlin/com/alibaba/testable/demo/DemoService.kt
rename to demo/kotlin-demo/src/main/kotlin/com/alibaba/testable/demo/service/DemoMockService.kt
index 41363b9..845d568 100644
--- a/demo/kotlin-demo/src/main/kotlin/com/alibaba/testable/demo/DemoService.kt
+++ b/demo/kotlin-demo/src/main/kotlin/com/alibaba/testable/demo/service/DemoMockService.kt
@@ -1,46 +1,32 @@
-package com.alibaba.testable.demo
+package com.alibaba.testable.demo.service
+import com.alibaba.testable.demo.model.BlackBox
+import com.alibaba.testable.demo.model.Box
+import com.alibaba.testable.demo.model.ColorBox
import org.springframework.stereotype.Service
import sun.net.www.http.HttpClient
import java.net.URL
@Service
-class DemoService {
-
- private var count = 0
+class DemoMockService {
/**
- * Target 1 - private method
- */
- private fun privateFunc(s: String, i: Int): String {
- return "$s - $i"
- }
-
- /**
- * Target 2 - method with private field access
- */
- fun privateFieldAccessFunc(): String {
- count += 2
- return count.toString()
- }
-
- /**
- * Target 3 - method with new operation
+ * method with new operation
*/
fun newFunc(): String {
return BlackBox("something").get()
}
/**
- * Target 4 - method with member method invoke
+ * method with member method invoke
*/
fun outerFunc(s: String): String {
return "{ \"res\": \"" + innerFunc(s) + "\"}"
}
/**
- * Target 5 - method with common method invoke
+ * method with common method invoke
*/
fun commonFunc(): String {
val box = BlackBox("anything")
@@ -48,14 +34,14 @@ class DemoService {
}
/**
- * Target 6 - method with static method invoke
+ * method with static method invoke
*/
fun getBox(): BlackBox {
return ColorBox.createBox("Red", BlackBox.secretBox())
}
/**
- * Target 7 - method with override method invoke
+ * method with override method invoke
*/
fun putBox(): Box {
val box: Box = BlackBox("")
@@ -64,7 +50,7 @@ class DemoService {
}
/**
- * Target 8 - two methods invoke same private method
+ * two methods invoke same private method
*/
fun callerOne(): String {
return callFromDifferentMethod()
diff --git a/demo/kotlin-demo/src/main/kotlin/com/alibaba/testable/demo/service/DemoPrivateAccessService.kt b/demo/kotlin-demo/src/main/kotlin/com/alibaba/testable/demo/service/DemoPrivateAccessService.kt
new file mode 100644
index 0000000..5ded99d
--- /dev/null
+++ b/demo/kotlin-demo/src/main/kotlin/com/alibaba/testable/demo/service/DemoPrivateAccessService.kt
@@ -0,0 +1,26 @@
+package com.alibaba.testable.demo.service
+
+import org.springframework.stereotype.Service
+
+
+@Service
+class DemoPrivateAccessService {
+
+ private var count = 0
+
+ /**
+ * private method
+ */
+ private fun privateFunc(s: String, i: Int): String {
+ return "$s - $i"
+ }
+
+ /**
+ * method with private field access
+ */
+ fun privateFieldAccessFunc(): String {
+ count += 2
+ return count.toString()
+ }
+
+}
diff --git a/demo/kotlin-demo/src/main/kotlin/com/alibaba/testable/demo/PathUtil.kt b/demo/kotlin-demo/src/main/kotlin/com/alibaba/testable/demo/util/PathUtil.kt
similarity index 94%
rename from demo/kotlin-demo/src/main/kotlin/com/alibaba/testable/demo/PathUtil.kt
rename to demo/kotlin-demo/src/main/kotlin/com/alibaba/testable/demo/util/PathUtil.kt
index 183c8c1..9e0da2b 100644
--- a/demo/kotlin-demo/src/main/kotlin/com/alibaba/testable/demo/PathUtil.kt
+++ b/demo/kotlin-demo/src/main/kotlin/com/alibaba/testable/demo/util/PathUtil.kt
@@ -1,4 +1,4 @@
-package com.alibaba.testable.demo
+package com.alibaba.testable.demo.util
import java.io.File
import java.io.IOException
diff --git a/demo/kotlin-demo/src/test/kotlin/com/alibaba/testable/demo/DemoServiceTest.kt b/demo/kotlin-demo/src/test/kotlin/com/alibaba/testable/demo/service/DemoMockServiceTest.kt
similarity index 79%
rename from demo/kotlin-demo/src/test/kotlin/com/alibaba/testable/demo/DemoServiceTest.kt
rename to demo/kotlin-demo/src/test/kotlin/com/alibaba/testable/demo/service/DemoMockServiceTest.kt
index 2677872..f6c10c9 100644
--- a/demo/kotlin-demo/src/test/kotlin/com/alibaba/testable/demo/DemoServiceTest.kt
+++ b/demo/kotlin-demo/src/test/kotlin/com/alibaba/testable/demo/service/DemoMockServiceTest.kt
@@ -1,22 +1,22 @@
-package com.alibaba.testable.demo
+package com.alibaba.testable.demo.service
-import com.alibaba.testable.core.accessor.PrivateAccessor
import com.alibaba.testable.core.annotation.TestableMock
import com.alibaba.testable.core.tool.TestableTool.*
-import com.alibaba.testable.processor.annotation.EnablePrivateAccess
+import com.alibaba.testable.demo.model.BlackBox
+import com.alibaba.testable.demo.model.Box
+import com.alibaba.testable.demo.model.ColorBox
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
import java.util.concurrent.Executors
-@EnablePrivateAccess
-internal class DemoServiceTest {
+internal class DemoMockServiceTest {
@TestableMock(targetMethod = CONSTRUCTOR)
private fun createBlackBox(text: String) = BlackBox("mock_$text")
@TestableMock
- private fun innerFunc(self: DemoService, text: String) = "mock_$text"
+ private fun innerFunc(self: DemoMockService, text: String) = "mock_$text"
@TestableMock
private fun trim(self: BlackBox) = "trim_string"
@@ -43,7 +43,7 @@ internal class DemoServiceTest {
}
@TestableMock
- private fun callFromDifferentMethod(self: DemoService): String {
+ private fun callFromDifferentMethod(self: DemoMockService): String {
return if (TEST_CASE == "should_able_to_get_test_case_name") {
"mock_special"
} else {
@@ -54,19 +54,7 @@ internal class DemoServiceTest {
}
}
- private val demoService = DemoService()
-
- @Test
- fun should_able_to_mock_private_method() {
- assertEquals("hello - 1", PrivateAccessor.invoke(demoService, "privateFunc", "hello", 1))
- }
-
- @Test
- fun should_able_to_mock_private_field() {
- PrivateAccessor.set(demoService, "count", 3)
- assertEquals("5", demoService.privateFieldAccessFunc())
- assertEquals(5, PrivateAccessor.get(demoService, "count"))
- }
+ private val demoService = DemoMockService()
@Test
fun should_able_to_mock_new_object() {
diff --git a/demo/kotlin-demo/src/test/kotlin/com/alibaba/testable/demo/service/DemoPrivateAccessServiceTest.kt b/demo/kotlin-demo/src/test/kotlin/com/alibaba/testable/demo/service/DemoPrivateAccessServiceTest.kt
new file mode 100644
index 0000000..4192139
--- /dev/null
+++ b/demo/kotlin-demo/src/test/kotlin/com/alibaba/testable/demo/service/DemoPrivateAccessServiceTest.kt
@@ -0,0 +1,23 @@
+package com.alibaba.testable.demo.service
+
+import com.alibaba.testable.core.accessor.PrivateAccessor
+import org.junit.jupiter.api.Assertions.assertEquals
+import org.junit.jupiter.api.Test
+
+
+internal class DemoPrivateAccessServiceTest {
+
+ private val demoService = DemoPrivateAccessService()
+
+ @Test
+ fun should_able_to_mock_private_method() {
+ assertEquals("hello - 1", PrivateAccessor.invoke(demoService, "privateFunc", "hello", 1))
+ }
+
+ @Test
+ fun should_able_to_mock_private_field() {
+ PrivateAccessor.set(demoService, "count", 3)
+ assertEquals("5", demoService.privateFieldAccessFunc())
+ assertEquals(5, PrivateAccessor.get(demoService, "count"))
+ }
+}
diff --git a/demo/kotlin-demo/src/test/kotlin/com/alibaba/testable/demo/PathUtilTest.kt b/demo/kotlin-demo/src/test/kotlin/com/alibaba/testable/demo/util/PathUtilTest.kt
similarity index 92%
rename from demo/kotlin-demo/src/test/kotlin/com/alibaba/testable/demo/PathUtilTest.kt
rename to demo/kotlin-demo/src/test/kotlin/com/alibaba/testable/demo/util/PathUtilTest.kt
index 77b9d2e..fddd26b 100644
--- a/demo/kotlin-demo/src/test/kotlin/com/alibaba/testable/demo/PathUtilTest.kt
+++ b/demo/kotlin-demo/src/test/kotlin/com/alibaba/testable/demo/util/PathUtilTest.kt
@@ -1,8 +1,9 @@
-package com.alibaba.testable.demo
+package com.alibaba.testable.demo.util
import org.junit.jupiter.api.Test
import com.alibaba.testable.core.annotation.TestableMock
import com.alibaba.testable.core.tool.TestableTool.verify
+import com.alibaba.testable.demo.util.PathUtil
import java.io.File
class PathUtilTest {
diff --git a/docs/usage.md b/docs/usage.md
index 439dec6..f8b7d2f 100644
--- a/docs/usage.md
+++ b/docs/usage.md
@@ -51,7 +51,7 @@
若不希望看到IDE的语法错误提醒,或是在基于JVM的非Java语言项目里(譬如Kotlin语言),也可以借助`PrivateAccessor`工具类来实现私有成员的访问。
-效果见示例项目文件`DemoServiceTest.java`中的`should_able_to_mock_private_method()`和`should_able_to_mock_private_field()`测试用例。
+效果见`java-demo`和`kotlin-demo`示例项目中的`should_able_to_mock_private_method()`和`should_able_to_mock_private_field()`测试用例。
### Mock被测类的任意方法调用
@@ -61,9 +61,22 @@
此时被测类中所有对该需覆写方法的调用,将在单元测试运行时,将自动被替换为对上述自定义Mock方法的调用。
-**注意**:当遇到有两个需覆写的方法重名时,可将需覆写的方法名写到`@TestableMock`注解的`targetMethod`参数里,此时Mock方法自身就可以随意命名了。
+**注意**:也可以将需覆写的方法名写到`@TestableMock`注解的`targetMethod`参数里,这样Mock方法自身就可以随意命名了(当遇到重名的待覆写方法时特别有用)。
-示例项目文件`DemoServiceTest.java`中的`should_able_to_mock_common_method()`用例详细展示了这种用法。
+例如,被测类中有一处`"anything".substring(1, 2)`调用,我们希望在运行测试的时候将它换成一个固定字符串,则只需在测试类定义如下方法:
+
+```java
+// 原方法签名为`String substring(int, int)`
+// 调用此方法的对象`"anything"`类型为`String`
+// 则Mock方法签名在其参数列表首位增加一个类型为`String`的参数(名字随意)
+// 此参数可用于获得当时的实际调用者的值和上下文
+@TestableMock
+private String substring(String self, int i, int j) {
+ return "sub_string";
+}
+```
+
+完整代码示例见`java-demo`和`kotlin-demo`示例项目中的`should_able_to_mock_common_method()`测试用例。(由于Kotlin对String类型进行了魔改,故Kotlin示例中将被测方法在`BlackBox`类里加了一层封装)
**2. 覆写被测类自身的成员方法**
@@ -71,13 +84,36 @@
操作方法与前一种情况相同,Mock方法的第一个参数类型需与被测类相同,即可实现对被测类自身(不论是公有或私有)成员方法的覆写。
-详见示例项目文件`DemoServiceTest.java`中的`should_able_to_mock_member_method()`用例。
+例如,被测类中有一个签名为`String innerFunc(String)`的私有方法,我们希望在测试的时候将它替换掉,则只需在测试类定义如下方法:
+
+```java
+// 被测类型是`DemoMockService`
+// 因此在定义Mock方法时,在目标方法参数首位加一个类型为`DemoMockService`的参数(名字随意)
+@TestableMock
+private String innerFunc(DemoMockService self, String text) {
+ return "mock_" + text;
+}
+```
+
+完整代码示例见`java-demo`和`kotlin-demo`示例项目中的`should_able_to_mock_member_method()`测试用例。
**3. 覆写任意类的静态方法**
对于静态方法的Mock与普通方法相同。但需要注意的是,对于静态方法,传入Mock方法的第一个参数实际值始终是`null`。
-详见示例项目文件`DemoServiceTest.java`中的`should_able_to_mock_static_method()`用例。
+例如,在被测类中调用了`BlackBox`类型中的静态方法`secretBox()`,改方法签名为`BlackBox secretBox()`,则Mock方法如下:
+
+```java
+// 目标静态方法定义在`BlackBox`类型中
+// 在定义Mock方法时,在目标方法参数首位加一个类型为`BlackBox`的参数(名字随意)
+// 此参数仅用于标识目标类型,实际传入值将始终为`null`
+@TestableMock
+private BlackBox secretBox(BlackBox ignore) {
+ return new BlackBox("not_secret_box");
+}
+```
+
+完整代码示例见`java-demo`和`kotlin-demo`示例项目中的`should_able_to_mock_static_method()`测试用例。
**4. 覆写任意类的new操作**
@@ -85,10 +121,22 @@
此时被测类中所有用`new`创建指定类的操作(并使用了与Mock方法参数一致的构造函数)将被替换为对该自定义方法的调用。
-详见示例项目文件`DemoServiceTest.java`中的`should_able_to_mock_new_object()`用例。
+例如,在被测类中有一处`new BlackBox("something")`调用,希望在测试时将它换掉(通常是换成Mock对象,或换成使用测试参数创建的临时对象),则只需定义如下Mock方法:
+
+```java
+// 要覆写的构造函数签名为`BlackBox(String)`
+// 无需在Mock方法参数列表增加额外参数,由于使用了`targetMethod`参数,Mock方法的名称随意起
+// 此处的`CONSTRUCTOR`为`TestableTool`辅助类提供的常量,值为""
+@TestableMock(targetMethod = CONSTRUCTOR)
+private BlackBox createBlackBox(String text) {
+ return new BlackBox("mock_" + text);
+}
+```
+
+完整代码示例见`java-demo`和`kotlin-demo`示例项目中的`should_able_to_mock_new_object()`测试用例。
**5. 识别当前测试用例和调用来源**
在Mock方法中可以通过`TestableTool.TEST_CASE`和`TestableTool.SOURCE_METHOD`来识别**当前运行的测试用例名称**和**进入该Mock方法前的被测类方法名称**,从而区分处理不同的调用场景。
-详见示例项目文件`DemoServiceTest.java`中的`should_able_to_get_source_method_name()`和`should_able_to_get_test_case_name()`用例。
+完整代码示例见`java-demo`和`kotlin-demo`示例项目中的`should_able_to_get_source_method_name()`和`should_able_to_get_test_case_name()`测试用例。