diff --git a/demo/java-demo/src/main/java/com/alibaba/demo/basic/DemoInherit.java b/demo/java-demo/src/main/java/com/alibaba/demo/basic/DemoInherit.java index d60ea9e..f6a372d 100644 --- a/demo/java-demo/src/main/java/com/alibaba/demo/basic/DemoInherit.java +++ b/demo/java-demo/src/main/java/com/alibaba/demo/basic/DemoInherit.java @@ -1,11 +1,8 @@ package com.alibaba.demo.basic; -import com.alibaba.demo.basic.model.BlackBox; -import com.alibaba.demo.basic.model.Box; -import com.alibaba.demo.basic.model.Color; -import com.alibaba.demo.basic.model.BlackBox; -import com.alibaba.demo.basic.model.Box; -import com.alibaba.demo.basic.model.Color; +import com.alibaba.demo.basic.model.mock.BlackBox; +import com.alibaba.demo.basic.model.mock.Box; +import com.alibaba.demo.basic.model.mock.Color; /** * 演示父类变量引用子类对象时的Mock场景 diff --git a/demo/java-demo/src/main/java/com/alibaba/demo/basic/DemoMatcher.java b/demo/java-demo/src/main/java/com/alibaba/demo/basic/DemoMatcher.java index fb633a5..d603d33 100644 --- a/demo/java-demo/src/main/java/com/alibaba/demo/basic/DemoMatcher.java +++ b/demo/java-demo/src/main/java/com/alibaba/demo/basic/DemoMatcher.java @@ -1,8 +1,7 @@ package com.alibaba.demo.basic; -import com.alibaba.demo.basic.model.BlackBox; -import com.alibaba.demo.basic.model.BlackBox; +import com.alibaba.demo.basic.model.mock.BlackBox; import java.util.ArrayList; import java.util.HashMap; diff --git a/demo/java-demo/src/main/java/com/alibaba/demo/basic/DemoMock.java b/demo/java-demo/src/main/java/com/alibaba/demo/basic/DemoMock.java index 6ec9c8d..0495e1a 100644 --- a/demo/java-demo/src/main/java/com/alibaba/demo/basic/DemoMock.java +++ b/demo/java-demo/src/main/java/com/alibaba/demo/basic/DemoMock.java @@ -1,7 +1,6 @@ package com.alibaba.demo.basic; -import com.alibaba.demo.basic.model.BlackBox; -import com.alibaba.demo.basic.model.BlackBox; +import com.alibaba.demo.basic.model.mock.BlackBox; import java.nio.file.Files; import java.nio.file.Paths; diff --git a/demo/java-demo/src/main/java/com/alibaba/demo/basic/model/BlackBox.java b/demo/java-demo/src/main/java/com/alibaba/demo/basic/model/mock/BlackBox.java similarity index 89% rename from demo/java-demo/src/main/java/com/alibaba/demo/basic/model/BlackBox.java rename to demo/java-demo/src/main/java/com/alibaba/demo/basic/model/mock/BlackBox.java index 106743d..d1f0a15 100644 --- a/demo/java-demo/src/main/java/com/alibaba/demo/basic/model/BlackBox.java +++ b/demo/java-demo/src/main/java/com/alibaba/demo/basic/model/mock/BlackBox.java @@ -1,4 +1,4 @@ -package com.alibaba.demo.basic.model; +package com.alibaba.demo.basic.model.mock; public class BlackBox extends Box implements Color { diff --git a/demo/java-demo/src/main/java/com/alibaba/demo/basic/model/Box.java b/demo/java-demo/src/main/java/com/alibaba/demo/basic/model/mock/Box.java similarity index 79% rename from demo/java-demo/src/main/java/com/alibaba/demo/basic/model/Box.java rename to demo/java-demo/src/main/java/com/alibaba/demo/basic/model/mock/Box.java index 6d48e98..2c3c895 100644 --- a/demo/java-demo/src/main/java/com/alibaba/demo/basic/model/Box.java +++ b/demo/java-demo/src/main/java/com/alibaba/demo/basic/model/mock/Box.java @@ -1,4 +1,4 @@ -package com.alibaba.demo.basic.model; +package com.alibaba.demo.basic.model.mock; abstract public class Box { diff --git a/demo/java-demo/src/main/java/com/alibaba/demo/basic/model/Color.java b/demo/java-demo/src/main/java/com/alibaba/demo/basic/model/mock/Color.java similarity index 55% rename from demo/java-demo/src/main/java/com/alibaba/demo/basic/model/Color.java rename to demo/java-demo/src/main/java/com/alibaba/demo/basic/model/mock/Color.java index bd58550..18172da 100644 --- a/demo/java-demo/src/main/java/com/alibaba/demo/basic/model/Color.java +++ b/demo/java-demo/src/main/java/com/alibaba/demo/basic/model/mock/Color.java @@ -1,4 +1,4 @@ -package com.alibaba.demo.basic.model; +package com.alibaba.demo.basic.model.mock; public interface Color { diff --git a/demo/java-demo/src/main/java/com/alibaba/demo/basic/model/omni/Child.java b/demo/java-demo/src/main/java/com/alibaba/demo/basic/model/omni/Child.java new file mode 100644 index 0000000..c9d4e30 --- /dev/null +++ b/demo/java-demo/src/main/java/com/alibaba/demo/basic/model/omni/Child.java @@ -0,0 +1,43 @@ +package com.alibaba.demo.basic.model.omni; + +public class Child { + + /** + * An inner class + */ + public class SubChild { + private GrandChild gc; + + public GrandChild getGrandChild() { + return gc; + } + + public void setGrandChild(GrandChild grandChild) { + this.gc = grandChild; + } + } + + // ---------- Member fields ---------- + + private GrandChild gc; + + private EnumChild ec; + + // ---------- Getters and Setters ---------- + + public GrandChild getGrandChild() { + return gc; + } + + public void setGrandChild(GrandChild grandChild) { + this.gc = grandChild; + } + + public EnumChild getEnumChild() { + return ec; + } + + public void setEnumChild(EnumChild enumChild) { + this.ec = enumChild; + } +} diff --git a/demo/java-demo/src/main/java/com/alibaba/demo/basic/model/omni/EnumChild.java b/demo/java-demo/src/main/java/com/alibaba/demo/basic/model/omni/EnumChild.java new file mode 100644 index 0000000..4d661a7 --- /dev/null +++ b/demo/java-demo/src/main/java/com/alibaba/demo/basic/model/omni/EnumChild.java @@ -0,0 +1,15 @@ +package com.alibaba.demo.basic.model.omni; + +public enum EnumChild { + + /** + * demo value - 1 + */ + VAL1, + + /** + * demo value - 2 + */ + VAL2 + +} diff --git a/demo/java-demo/src/main/java/com/alibaba/demo/basic/model/omni/GrandChild.java b/demo/java-demo/src/main/java/com/alibaba/demo/basic/model/omni/GrandChild.java new file mode 100644 index 0000000..99600f6 --- /dev/null +++ b/demo/java-demo/src/main/java/com/alibaba/demo/basic/model/omni/GrandChild.java @@ -0,0 +1,22 @@ +package com.alibaba.demo.basic.model.omni; + +public class GrandChild { + + // ---------- Member fields ---------- + + private int value; + + // ---------- Constructor, Getters and Setters ---------- + + public GrandChild(int v) { + this.value = v; + } + + public int getValue() { + return value; + } + + public void setValue(int value) { + this.value = value; + } +} diff --git a/demo/java-demo/src/main/java/com/alibaba/demo/basic/model/omni/Parent.java b/demo/java-demo/src/main/java/com/alibaba/demo/basic/model/omni/Parent.java new file mode 100644 index 0000000..d96071c --- /dev/null +++ b/demo/java-demo/src/main/java/com/alibaba/demo/basic/model/omni/Parent.java @@ -0,0 +1,39 @@ +package com.alibaba.demo.basic.model.omni; + +public class Parent { + + // ---------- Member fields ---------- + + private Child c; + + private Child[] cs; + + private Child.SubChild sc; + + // ---------- Getters and Setters ---------- + + public Child getChild() { + return c; + } + + public void setChild(Child child) { + this.c = child; + } + + public Child[] getChildren() { + return cs; + } + + public void setChildren(Child[] children) { + this.cs = children; + } + + public Child.SubChild getSubChild() { + return sc; + } + + public void setSubChild(Child.SubChild subChild) { + this.sc = subChild; + } + +} diff --git a/demo/java-demo/src/test/java/com/alibaba/demo/basic/DemoInheritTest.java b/demo/java-demo/src/test/java/com/alibaba/demo/basic/DemoInheritTest.java index 97f06d2..c6c53cb 100644 --- a/demo/java-demo/src/test/java/com/alibaba/demo/basic/DemoInheritTest.java +++ b/demo/java-demo/src/test/java/com/alibaba/demo/basic/DemoInheritTest.java @@ -1,13 +1,9 @@ package com.alibaba.demo.basic; -import com.alibaba.demo.basic.model.BlackBox; -import com.alibaba.demo.basic.model.Box; -import com.alibaba.demo.basic.model.Color; +import com.alibaba.demo.basic.model.mock.BlackBox; +import com.alibaba.demo.basic.model.mock.Box; +import com.alibaba.demo.basic.model.mock.Color; import com.alibaba.testable.core.annotation.MockMethod; -import com.alibaba.demo.basic.DemoInherit; -import com.alibaba.demo.basic.model.BlackBox; -import com.alibaba.demo.basic.model.Box; -import com.alibaba.demo.basic.model.Color; import org.junit.jupiter.api.Test; import static com.alibaba.testable.core.matcher.InvokeVerifier.verify; @@ -54,42 +50,42 @@ class DemoInheritTest { } @Test - void should_able_to_mock_call_sub_object_method_by_parent_object() { + void should_mock_call_sub_object_method_by_parent_object() { BlackBox box = (BlackBox)demoInherit.putIntoBox(); verify("put_into_box").withTimes(1); assertEquals("put_data_into_box", box.get()); } @Test - void should_able_to_mock_call_sub_object_method_by_sub_object() { + void should_mock_call_sub_object_method_by_sub_object() { BlackBox box = demoInherit.putIntoBlackBox(); verify("put_into_blackbox").withTimes(1); assertEquals("put_data_into_blackbox", box.get()); } @Test - void should_able_to_mock_call_parent_object_method_by_parent_object() { + void should_mock_call_parent_object_method_by_parent_object() { String content = demoInherit.getFromBox(); verify("get_from_box").withTimes(1); assertEquals("get_from_box", content); } @Test - void should_able_to_mock_call_parent_object_method_by_sub_object() { + void should_mock_call_parent_object_method_by_sub_object() { String content = demoInherit.getFromBlackBox(); verify("get_from_blackbox").withTimes(1); assertEquals("get_from_blackbox", content); } @Test - void should_able_to_mock_call_interface_method_by_interface_object() { + void should_mock_call_interface_method_by_interface_object() { String color = demoInherit.getColorViaColor(); verify("get_color_from_color").withTimes(1); assertEquals("color_from_color", color); } @Test - void should_able_to_mock_call_interface_method_by_sub_class_object() { + void should_mock_call_interface_method_by_sub_class_object() { String color = demoInherit.getColorViaBox(); verify("get_color_from_blackbox").withTimes(1); assertEquals("color_from_blackbox", color); diff --git a/demo/java-demo/src/test/java/com/alibaba/demo/basic/DemoInnerClassTest.java b/demo/java-demo/src/test/java/com/alibaba/demo/basic/DemoInnerClassTest.java index 8a363c7..d0c2b86 100644 --- a/demo/java-demo/src/test/java/com/alibaba/demo/basic/DemoInnerClassTest.java +++ b/demo/java-demo/src/test/java/com/alibaba/demo/basic/DemoInnerClassTest.java @@ -19,7 +19,7 @@ class DemoInnerClassTest { } @Test - void should_able_to_mock_invoke_inside_inner_class() throws Exception { + void should_mock_invoke_inside_inner_class() throws Exception { DemoInnerClass demo = new DemoInnerClass(); assertEquals("MockedCall", demo.callInnerDemo()); assertEquals("MockedCall", demo.callAnonymousInner()); diff --git a/demo/java-demo/src/test/java/com/alibaba/demo/basic/DemoMatcherTest.java b/demo/java-demo/src/test/java/com/alibaba/demo/basic/DemoMatcherTest.java index 60abc82..3dd916e 100644 --- a/demo/java-demo/src/test/java/com/alibaba/demo/basic/DemoMatcherTest.java +++ b/demo/java-demo/src/test/java/com/alibaba/demo/basic/DemoMatcherTest.java @@ -1,10 +1,8 @@ package com.alibaba.demo.basic; -import com.alibaba.demo.basic.model.BlackBox; +import com.alibaba.demo.basic.model.mock.BlackBox; import com.alibaba.testable.core.annotation.MockMethod; import com.alibaba.testable.core.error.VerifyFailedError; -import com.alibaba.demo.basic.DemoMatcher; -import com.alibaba.demo.basic.model.BlackBox; import org.junit.jupiter.api.Test; import static com.alibaba.testable.core.matcher.InvokeMatcher.*; diff --git a/demo/java-demo/src/test/java/com/alibaba/demo/basic/DemoMockTest.java b/demo/java-demo/src/test/java/com/alibaba/demo/basic/DemoMockTest.java index fa68d93..e587501 100644 --- a/demo/java-demo/src/test/java/com/alibaba/demo/basic/DemoMockTest.java +++ b/demo/java-demo/src/test/java/com/alibaba/demo/basic/DemoMockTest.java @@ -1,9 +1,8 @@ package com.alibaba.demo.basic; -import com.alibaba.demo.basic.model.BlackBox; +import com.alibaba.demo.basic.model.mock.BlackBox; import com.alibaba.testable.core.annotation.MockConstructor; import com.alibaba.testable.core.annotation.MockMethod; -import com.alibaba.demo.basic.model.BlackBox; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -73,20 +72,20 @@ class DemoMockTest { } @Test - void should_able_to_mock_new_object() { + void should_mock_new_object() { assertEquals("mock_something", demoMock.newFunc()); verify("createBlackBox").with("something"); } @Test - void should_able_to_mock_member_method() throws Exception { + void should_mock_member_method() throws Exception { assertEquals("{ \"res\": \"mock_hello_MOCK_TAIL\"}", demoMock.outerFunc("hello")); verify("innerFunc").with("hello"); verify("staticFunc").with(); } @Test - void should_able_to_mock_common_method() { + void should_mock_common_method() { assertEquals("trim_string__sub_string__false", demoMock.commonFunc()); verify("trim").withTimes(1); verify("sub").withTimes(1); @@ -94,13 +93,13 @@ class DemoMockTest { } @Test - void should_able_to_mock_static_method() { + void should_mock_static_method() { Assertions.assertEquals("not_secret_box", demoMock.getBox().get()); verify("secretBox").withTimes(1); } @Test - void should_able_to_get_source_method_name() throws Exception { + void should_get_source_method_name() throws Exception { // synchronous assertEquals("mock_one_mock_others", demoMock.callerOne() + "_" + demoMock.callerTwo()); // asynchronous @@ -110,7 +109,7 @@ class DemoMockTest { } @Test - void should_able_to_set_mock_context() throws Exception { + void should_set_mock_context() throws Exception { MOCK_CONTEXT.put("case", "special_case"); // synchronous assertEquals("mock_special", demoMock.callerOne()); diff --git a/demo/java-demo/src/test/java/com/alibaba/demo/basic/DemoOmniMethodsTest.java b/demo/java-demo/src/test/java/com/alibaba/demo/basic/DemoOmniMethodsTest.java new file mode 100644 index 0000000..71f1a7d --- /dev/null +++ b/demo/java-demo/src/test/java/com/alibaba/demo/basic/DemoOmniMethodsTest.java @@ -0,0 +1,54 @@ +package com.alibaba.demo.basic; + +import com.alibaba.demo.basic.model.omni.Child; +import com.alibaba.demo.basic.model.omni.EnumChild; +import com.alibaba.demo.basic.model.omni.GrandChild; +import com.alibaba.demo.basic.model.omni.Parent; +import com.alibaba.testable.core.tool.OmniAccessor; +import com.alibaba.testable.core.tool.OmniConstructor; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * 演示快速创建任意对象和使用路径访问成员 + * Demonstrate quick object construction and access members by path + */ +class DemoOmniMethodsTest { + + @Test + void should_construct_any_class() { + // 所有基础类型初始化为默认数值 + GrandChild aGrandChild = OmniConstructor.newInstance(GrandChild.class); + assertEquals(0, aGrandChild.getValue()); + + // 所有枚举类型初始化为第一个可选值 + Child aChild = OmniConstructor.newInstance(Child.class); + assertEquals(EnumChild.VAL1, aChild.getEnumChild()); + + // 所有数组类型初始化为空数组 + // 所有子孙成员对象都会逐级初始化 + Parent aParent = OmniConstructor.newInstance(Parent.class); + assertEquals(0, aParent.getChildren().length); + assertEquals(0, aParent.getSubChild().getGrandChild().getValue()); + } + + @Test + void should_get_any_member() { + Parent demo = OmniConstructor.newInstance(Parent.class); + + demo.getChild().setEnumChild(EnumChild.VAL2); + assertEquals(EnumChild.VAL2, OmniAccessor.get(demo, "ec")); + assertEquals(EnumChild.VAL2, OmniAccessor.get(demo, "{EnumChild}")); + assertEquals(EnumChild.VAL2, OmniAccessor.get(demo, "c/ec")); + + demo.setChildren(new Child[]{ new Child() }); + assertEquals(EnumChild.VAL1, OmniAccessor.get(demo, "cs[0]/ec")); + } + + @Test + void should_set_any_member() { + + } + +} diff --git a/demo/java-demo/src/test/java/com/alibaba/demo/basic/DemoPrivateAccessTest.java b/demo/java-demo/src/test/java/com/alibaba/demo/basic/DemoPrivateAccessTest.java index 7334640..1803b76 100644 --- a/demo/java-demo/src/test/java/com/alibaba/demo/basic/DemoPrivateAccessTest.java +++ b/demo/java-demo/src/test/java/com/alibaba/demo/basic/DemoPrivateAccessTest.java @@ -21,7 +21,7 @@ class DemoPrivateAccessTest { private DemoPrivateAccess demoPrivateAccess = new DemoPrivateAccess(); @Test - void should_able_to_access_private_method() { + void should_access_private_method() { List list = new ArrayList() {{ add("a"); add("b"); add("c"); }}; assertEquals("member", demoPrivateAccess.privateFunc()); assertEquals("member", PrivateAccessor.invoke(demoPrivateAccess, "privateFunc")); @@ -30,7 +30,7 @@ class DemoPrivateAccessTest { } @Test - void should_able_to_access_private_field() { + void should_access_private_field() { demoPrivateAccess.count = 2; assertEquals(Integer.valueOf(2), demoPrivateAccess.count); @@ -39,7 +39,7 @@ class DemoPrivateAccessTest { } @Test - void should_able_to_access_private_static_method() { + void should_access_private_static_method() { assertEquals("static", DemoPrivateAccess.privateStaticFunc()); assertEquals("static", PrivateAccessor.invokeStatic(DemoPrivateAccess.class, "privateStaticFunc")); assertEquals("hello + 1", DemoPrivateAccess.privateStaticFuncWithArgs("hello", 1)); @@ -47,7 +47,7 @@ class DemoPrivateAccessTest { } @Test - void should_able_to_access_private_static_field() { + void should_access_private_static_field() { DemoPrivateAccess.staticCount = 2; assertEquals(Integer.valueOf(2), DemoPrivateAccess.staticCount); @@ -56,7 +56,7 @@ class DemoPrivateAccessTest { } @Test - void should_able_to_update_final_field() { + void should_update_final_field() { demoPrivateAccess.pi = 4.13; assertEquals(Double.valueOf(4.13), demoPrivateAccess.pi); @@ -65,7 +65,7 @@ class DemoPrivateAccessTest { } @Test - void should_able_to_use_null_parameter() { + void should_use_null_parameter() { demoPrivateAccess.pi = null; assertNull(demoPrivateAccess.pi); assertEquals("null + 1", DemoPrivateAccess.privateStaticFuncWithArgs(null, 1)); diff --git a/demo/java-demo/src/test/java/com/alibaba/demo/basic/DemoTemplateTest.java b/demo/java-demo/src/test/java/com/alibaba/demo/basic/DemoTemplateTest.java index c1c84b2..7742f96 100644 --- a/demo/java-demo/src/test/java/com/alibaba/demo/basic/DemoTemplateTest.java +++ b/demo/java-demo/src/test/java/com/alibaba/demo/basic/DemoTemplateTest.java @@ -72,19 +72,19 @@ class DemoTemplateTest { } @Test - void should_able_to_mock_single_template_method() { + void should_mock_single_template_method() { String res = demoTemplate.singleTemplateMethod(); assertEquals("demo_mock_list", res); } @Test - void should_able_to_mock_double_template_method() { + void should_mock_double_template_method() { String res = demoTemplate.doubleTemplateMethod(); assertEquals("testable_mock_map", res); } @Test - void should_able_to_mock_new_template_method() { + void should_mock_new_template_method() { Set res = demoTemplate.newTemplateMethod(); assertEquals(2, res.size()); Iterator iterator = res.stream().iterator(); diff --git a/demo/java-demo/src/test/java/com/alibaba/demo/one2multi/OneToMultiSvcTest.java b/demo/java-demo/src/test/java/com/alibaba/demo/one2multi/OneToMultiSvcTest.java index becca65..228838a 100644 --- a/demo/java-demo/src/test/java/com/alibaba/demo/one2multi/OneToMultiSvcTest.java +++ b/demo/java-demo/src/test/java/com/alibaba/demo/one2multi/OneToMultiSvcTest.java @@ -15,7 +15,7 @@ public class OneToMultiSvcTest { private CSvc cSvc = new CSvc(); @Test - public void should_able_to_test_multi_class_together() { + public void should_test_multi_class_together() { assertEquals("a_mock", aSvc.demo("test")); assertEquals("b_mock", bSvc.demo("test")); assertEquals("c_mock", cSvc.demo("test")); diff --git a/demo/kotlin-demo/src/test/kotlin/com/alibaba/demo/basic/DemoInheritTest.kt b/demo/kotlin-demo/src/test/kotlin/com/alibaba/demo/basic/DemoInheritTest.kt index a3c2ef6..4835d3b 100644 --- a/demo/kotlin-demo/src/test/kotlin/com/alibaba/demo/basic/DemoInheritTest.kt +++ b/demo/kotlin-demo/src/test/kotlin/com/alibaba/demo/basic/DemoInheritTest.kt @@ -49,42 +49,42 @@ internal class DemoInheritTest { } @Test - fun should_able_to_mock_call_sub_object_method_by_parent_object() { + fun should_mock_call_sub_object_method_by_parent_object() { val box = demoInherit.putIntoBox() as BlackBox InvokeVerifier.verify("put_into_box").withTimes(1) Assertions.assertEquals("put_data_into_box", box.get()) } @Test - fun should_able_to_mock_call_sub_object_method_by_sub_object() { + fun should_mock_call_sub_object_method_by_sub_object() { val box = demoInherit.putIntoBlackBox() InvokeVerifier.verify("put_into_blackbox").withTimes(1) Assertions.assertEquals("put_data_into_blackbox", box.get()) } @Test - fun should_able_to_mock_call_parent_object_method_by_parent_object() { + fun should_mock_call_parent_object_method_by_parent_object() { val content = demoInherit.fromBox InvokeVerifier.verify("get_from_box").withTimes(1) Assertions.assertEquals("get_from_box", content) } @Test - fun should_able_to_mock_call_parent_object_method_by_sub_object() { + fun should_mock_call_parent_object_method_by_sub_object() { val content = demoInherit.fromBlackBox InvokeVerifier.verify("get_from_blackbox").withTimes(1) Assertions.assertEquals("get_from_blackbox", content) } @Test - fun should_able_to_mock_call_interface_method_by_interface_object() { + fun should_mock_call_interface_method_by_interface_object() { val color = demoInherit.colorViaColor InvokeVerifier.verify("get_color_from_color").withTimes(1) Assertions.assertEquals("color_from_color", color) } @Test - fun should_able_to_mock_call_interface_method_by_sub_class_object() { + fun should_mock_call_interface_method_by_sub_class_object() { val color = demoInherit.colorViaBox InvokeVerifier.verify("get_color_from_blackbox").withTimes(1) Assertions.assertEquals("color_from_blackbox", color) diff --git a/demo/kotlin-demo/src/test/kotlin/com/alibaba/demo/basic/DemoInnerClassTest.kt b/demo/kotlin-demo/src/test/kotlin/com/alibaba/demo/basic/DemoInnerClassTest.kt index a4b2150..92e9923 100644 --- a/demo/kotlin-demo/src/test/kotlin/com/alibaba/demo/basic/DemoInnerClassTest.kt +++ b/demo/kotlin-demo/src/test/kotlin/com/alibaba/demo/basic/DemoInnerClassTest.kt @@ -19,7 +19,7 @@ internal class DemoInnerClassTest { @Test @Throws(Exception::class) - fun should_able_to_mock_invoke_inside_inner_class() { + fun should_mock_invoke_inside_inner_class() { val demo = DemoInnerClass() Assertions.assertEquals("MockedCall", demo.callInnerDemo()) Assertions.assertEquals("MockedCall", demo.callAnonymousInner()) diff --git a/demo/kotlin-demo/src/test/kotlin/com/alibaba/demo/basic/DemoMockTest.kt b/demo/kotlin-demo/src/test/kotlin/com/alibaba/demo/basic/DemoMockTest.kt index e0ef426..e167d1e 100644 --- a/demo/kotlin-demo/src/test/kotlin/com/alibaba/demo/basic/DemoMockTest.kt +++ b/demo/kotlin-demo/src/test/kotlin/com/alibaba/demo/basic/DemoMockTest.kt @@ -64,26 +64,26 @@ internal class DemoMockTest { } @Test - fun should_able_to_mock_new_object() { + fun should_mock_new_object() { assertEquals("mock_something", demoMock.newFunc()) verify("createBlackBox").with("something") } @Test - fun should_able_to_mock_member_method() { + fun should_mock_member_method() { assertEquals("{ \"res\": \"mock_hello_MOCK_TAIL\"}", demoMock.outerFunc("hello")) verify("innerFunc").with("hello") verify("staticFunc").with() } // @Test -// fun should_able_to_mock_method_in_companion_object() { +// fun should_mock_method_in_companion_object() { // assertEquals("CALL_MOCK_TAIL", DemoMock.callStaticFunc()) // verify("staticFunc").with() // } @Test - fun should_able_to_mock_common_method() { + fun should_mock_common_method() { assertEquals("trim_string__sub_string__false", demoMock.commonFunc()) verify("trim").withTimes(1) verify("sub").withTimes(1) @@ -91,14 +91,14 @@ internal class DemoMockTest { } @Test - fun should_able_to_mock_static_method() { + fun should_mock_static_method() { assertEquals("White_not_secret_box", demoMock.getBox().get()) verify("secretBox").withTimes(1) verify("createBox").withTimes(1) } @Test - fun should_able_to_get_source_method_name() { + fun should_get_source_method_name() { // synchronous assertEquals("mock_one_mock_others", demoMock.callerOne() + "_" + demoMock.callerTwo()) // asynchronous @@ -109,7 +109,7 @@ internal class DemoMockTest { } @Test - fun should_able_to_get_test_case_name() { + fun should_get_test_case_name() { MOCK_CONTEXT["case"] = "special_case" // synchronous assertEquals("mock_special", demoMock.callerOne()) diff --git a/demo/kotlin-demo/src/test/kotlin/com/alibaba/demo/basic/DemoPrivateAccessTest.kt b/demo/kotlin-demo/src/test/kotlin/com/alibaba/demo/basic/DemoPrivateAccessTest.kt index 7fdcf29..c6656e2 100644 --- a/demo/kotlin-demo/src/test/kotlin/com/alibaba/demo/basic/DemoPrivateAccessTest.kt +++ b/demo/kotlin-demo/src/test/kotlin/com/alibaba/demo/basic/DemoPrivateAccessTest.kt @@ -13,32 +13,32 @@ internal class DemoPrivateAccessTest { private val demoPrivateAccess = DemoPrivateAccess() @Test - fun should_able_to_access_private_method() { + fun should_access_private_method() { val list = listOf("a", "b", "c"); assertEquals("abc + hello + 1", PrivateAccessor.invoke(demoPrivateAccess, "privateFunc", list, "hello", 1)) } @Test - fun should_able_to_access_private_field() { + fun should_access_private_field() { PrivateAccessor.set(demoPrivateAccess, "count", 3) assertEquals(3, PrivateAccessor.get(demoPrivateAccess, "count")) } @Test - fun should_able_to_access_private_static_method() { + fun should_access_private_static_method() { val list = listOf("a", "b", "c"); assertEquals("hello + 1", PrivateAccessor.invokeStatic(DemoPrivateAccess::class.java, "privateStaticFunc", "hello", 1)) assertEquals("abc * hello * 1", PrivateAccessor.invokeStatic(DemoPrivateAccess::class.java, "privateJvmStaticFunc", list, "hello", 1)) } @Test - fun should_able_to_access_private_static_field() { + fun should_access_private_static_field() { PrivateAccessor.setStatic(DemoPrivateAccess::class.java, "staticCount", 3) assertEquals(3, PrivateAccessor.getStatic(DemoPrivateAccess::class.java, "staticCount")) } @Test - fun should_able_to_update_final_field() { + fun should_update_final_field() { PrivateAccessor.set(demoPrivateAccess, "pi", 4.13) assertEquals(4.13, demoPrivateAccess.pi) } diff --git a/demo/kotlin-demo/src/test/kotlin/com/alibaba/demo/basic/DemoTemplateTest.kt b/demo/kotlin-demo/src/test/kotlin/com/alibaba/demo/basic/DemoTemplateTest.kt index 455eec0..8146697 100644 --- a/demo/kotlin-demo/src/test/kotlin/com/alibaba/demo/basic/DemoTemplateTest.kt +++ b/demo/kotlin-demo/src/test/kotlin/com/alibaba/demo/basic/DemoTemplateTest.kt @@ -40,19 +40,19 @@ internal class DemoTemplateTest { } @Test - fun should_able_to_mock_single_template_method() { + fun should_mock_single_template_method() { val res = demoTemplate.singleTemplateMethod() Assertions.assertEquals("demo_mock_list", res) } @Test - fun should_able_to_mock_double_template_method() { + fun should_mock_double_template_method() { val res = demoTemplate.doubleTemplateMethod() Assertions.assertEquals("testable_mock_map", res) } @Test - fun should_able_to_mock_new_template_method() { + fun should_mock_new_template_method() { val res = demoTemplate.newTemplateMethod() Assertions.assertEquals(2, res.size) val iterator = res.stream().iterator() diff --git a/demo/kotlin-demo/src/test/kotlin/com/alibaba/demo/java2kotlin/PathUtilTest.kt b/demo/kotlin-demo/src/test/kotlin/com/alibaba/demo/java2kotlin/PathUtilTest.kt index 1341c17..e7ac833 100644 --- a/demo/kotlin-demo/src/test/kotlin/com/alibaba/demo/java2kotlin/PathUtilTest.kt +++ b/demo/kotlin-demo/src/test/kotlin/com/alibaba/demo/java2kotlin/PathUtilTest.kt @@ -41,7 +41,7 @@ class PathUtilTest { } @Test - fun should_able_to_mock_java_method_invoke_in_kotlin() { + fun should_mock_java_method_invoke_in_kotlin() { PathUtil.deleteRecursively(File("/a/b/")) verify("listFiles").withTimes(2) verify("delete").withTimes(4) diff --git a/demo/kotlin-demo/src/test/kotlin/com/alibaba/demo/one2multi/OneToMultiSvcTest.kt b/demo/kotlin-demo/src/test/kotlin/com/alibaba/demo/one2multi/OneToMultiSvcTest.kt index 98f5642..846ade4 100644 --- a/demo/kotlin-demo/src/test/kotlin/com/alibaba/demo/one2multi/OneToMultiSvcTest.kt +++ b/demo/kotlin-demo/src/test/kotlin/com/alibaba/demo/one2multi/OneToMultiSvcTest.kt @@ -13,7 +13,7 @@ class OneToMultiSvcTest { private val cSvc = CSvc() @Test - fun should_able_to_test_multi_class_together() { + fun should_test_multi_class_together() { Assertions.assertEquals("a_mock", aSvc.demo("test")) Assertions.assertEquals("b_mock", bSvc.demo("test")) Assertions.assertEquals("c_mock", cSvc.demo("test")) diff --git a/docs/en-us/doc/troubleshooting.md b/docs/en-us/doc/troubleshooting.md index 7c228ef..d7203c4 100644 --- a/docs/en-us/doc/troubleshooting.md +++ b/docs/en-us/doc/troubleshooting.md @@ -54,9 +54,9 @@ Executing the unit test again will print out the signatures of all mock methods, ```text [DIAGNOSE] Handling test class com/alibaba/testable/demo/basic/DemoMockTest -[VERBOSE] Test case "should_able_to_mock_new_object" +[VERBOSE] Test case "should_mock_new_object" ... ... -[VERBOSE] Test case "should_able_to_set_mock_context" +[VERBOSE] Test case "should_set_mock_context" [DIAGNOSE] Found 6 test cases [DIAGNOSE] Handling mock class com/alibaba/testable/demo/basic/DemoMockTest$Mock [VERBOSE] Mock constructor "createBlackBox" as "com.alibaba.demo.basic.model.BlackBox(java.lang.String)" diff --git a/docs/en-us/doc/upgrade-to-v05.md b/docs/en-us/doc/upgrade-to-v05.md index fb7c2c2..1fa847c 100644 --- a/docs/en-us/doc/upgrade-to-v05.md +++ b/docs/en-us/doc/upgrade-to-v05.md @@ -19,7 +19,7 @@ public class DemoMockTest { } @Test - void should_able_to_mock_member_method() throws Exception { + void should_mock_member_method() throws Exception { assertEquals("hello_world", demoMock.outerFunc()); verify("innerFunc").with("world"); } @@ -39,7 +39,7 @@ public class DemoMockTest { } // Add this line @Test - void should_able_to_mock_member_method() throws Exception { + void should_mock_member_method() throws Exception { assertEquals("hello_world", demoMock.outerFunc()); verify("innerFunc").with("world"); } diff --git a/docs/en-us/doc/use-mock.md b/docs/en-us/doc/use-mock.md index 109db06..4f98425 100644 --- a/docs/en-us/doc/use-mock.md +++ b/docs/en-us/doc/use-mock.md @@ -67,7 +67,7 @@ private String substring(String self, int i, int j) { } ``` -For complete code examples, see the `should_able_to_mock_common_method()` test cases in the `java-demo` and `kotlin-demo` sample projects. (Because Kotlin has made magical changes to the String type, the method under test in the Kotlin example adds a layer of encapsulation to the `BlackBox` class) +For complete code examples, see the `should_mock_common_method()` test cases in the `java-demo` and `kotlin-demo` sample projects. (Because Kotlin has made magical changes to the String type, the method under test in the Kotlin example adds a layer of encapsulation to the `BlackBox` class) #### 2. Mock the member method of the class under test itself @@ -87,7 +87,7 @@ private String innerFunc(String text) { Similarly, if the method in the above example needs to access the original tested object that initiated the call, it may not use the `targetClass` parameter, but when defining the mock method, add a parameter of type `DemoMock` to the first index of the method parameter list. -For complete code examples, see the `should_able_to_mock_member_method()` test case in the `java-demo` and `kotlin-demo` sample projects. +For complete code examples, see the `should_mock_member_method()` test case in the `java-demo` and `kotlin-demo` sample projects. #### 3. Mock static methods of any class @@ -102,7 +102,7 @@ private BlackBox secretBox() { } ``` -For complete code examples, see the `should_able_to_mock_static_method()` test case in the `java-demo` and `kotlin-demo` sample projects. +For complete code examples, see the `should_mock_static_method()` test case in the `java-demo` and `kotlin-demo` sample projects. #### 4. Mock `new` operation of any type @@ -123,7 +123,7 @@ private BlackBox createBlackBox(String text) { > You can still use the `@MockMethod` annotation, and configure the `targetMethod` parameter value to `""`, and the rest is the same as above. The effect is the same as using the `@MockContructor` annotation -For complete code examples, see the `should_able_to_mock_new_object()` test case in the `java-demo` and `kotlin-demo` sample projects. +For complete code examples, see the `should_mock_new_object()` test case in the `java-demo` and `kotlin-demo` sample projects. #### 5. Identify different invocation source in mock method @@ -157,7 +157,7 @@ private Data mockDemo() { } ``` -For complete code examples, see the `should_able_to_get_source_method_name()` and `should_able_to_get_test_case_name()` test cases in the `java-demo` and `kotlin-demo` sample projects. +For complete code examples, see the `should_get_source_method_name()` and `should_get_test_case_name()` test cases in the `java-demo` and `kotlin-demo` sample projects. #### 6. Verify the sequence and parameters of the mock method being invoked diff --git a/docs/zh-cn/doc/troubleshooting.md b/docs/zh-cn/doc/troubleshooting.md index e97cd80..c30774f 100644 --- a/docs/zh-cn/doc/troubleshooting.md +++ b/docs/zh-cn/doc/troubleshooting.md @@ -59,9 +59,9 @@ class DemoTest { ```text [DIAGNOSE] Handling test class com/alibaba/testable/demo/basic/DemoMockTest -[VERBOSE] Test case "should_able_to_mock_new_object" +[VERBOSE] Test case "should_mock_new_object" ... ... -[VERBOSE] Test case "should_able_to_set_mock_context" +[VERBOSE] Test case "should_set_mock_context" [DIAGNOSE] Found 6 test cases [DIAGNOSE] Handling mock class com/alibaba/testable/demo/basic/DemoMockTest$Mock [VERBOSE] Mock constructor "createBlackBox" as "com.alibaba.demo.basic.model.BlackBox(java.lang.String)" diff --git a/docs/zh-cn/doc/upgrade-to-v05.md b/docs/zh-cn/doc/upgrade-to-v05.md index 17affb4..4af0046 100644 --- a/docs/zh-cn/doc/upgrade-to-v05.md +++ b/docs/zh-cn/doc/upgrade-to-v05.md @@ -19,7 +19,7 @@ public class DemoMockTest { } @Test - void should_able_to_mock_member_method() throws Exception { + void should_mock_member_method() throws Exception { assertEquals("hello_world", demoMock.outerFunc()); verify("innerFunc").with("world"); } @@ -39,7 +39,7 @@ public class DemoMockTest { } // 增加此行 @Test - void should_able_to_mock_member_method() throws Exception { + void should_mock_member_method() throws Exception { assertEquals("hello_world", demoMock.outerFunc()); verify("innerFunc").with("world"); } diff --git a/docs/zh-cn/doc/use-mock.md b/docs/zh-cn/doc/use-mock.md index 152f281..4d43d85 100644 --- a/docs/zh-cn/doc/use-mock.md +++ b/docs/zh-cn/doc/use-mock.md @@ -67,7 +67,7 @@ private String substring(String self, int i, int j) { } ``` -完整代码示例见`java-demo`和`kotlin-demo`示例项目中的`should_able_to_mock_common_method()`测试用例。(由于Kotlin对String类型进行了魔改,故Kotlin示例中将被测方法在`BlackBox`类里加了一层封装) +完整代码示例见`java-demo`和`kotlin-demo`示例项目中的`should_mock_common_method()`测试用例。(由于Kotlin对String类型进行了魔改,故Kotlin示例中将被测方法在`BlackBox`类里加了一层封装) #### 2. 覆写被测类自身的成员方法 @@ -87,7 +87,7 @@ private String innerFunc(String text) { 同样的,上述示例中的方法如需访问发起调用的原始被测对象,也可不使用`targetClass`参数,而是在定义Mock方法时,在方法参数列表首位加一个类型为`DemoMock`的参数(名字随意)。 -完整代码示例见`java-demo`和`kotlin-demo`示例项目中的`should_able_to_mock_member_method()`测试用例。 +完整代码示例见`java-demo`和`kotlin-demo`示例项目中的`should_mock_member_method()`测试用例。 #### 3. 覆写任意类的静态方法 @@ -104,7 +104,7 @@ private BlackBox secretBox() { 对于静态方法的Mock,通常不使用方法参数列表的首位加参数来表示目标类型。但这种方法也依然适用,只是实际传入的第一个参数值将始终是`null`。 -完整代码示例见`java-demo`和`kotlin-demo`示例项目中的`should_able_to_mock_static_method()`测试用例。 +完整代码示例见`java-demo`和`kotlin-demo`示例项目中的`should_mock_static_method()`测试用例。 #### 4. 覆写任意类的new操作 @@ -123,7 +123,7 @@ private BlackBox createBlackBox(String text) { } ``` -完整代码示例见`java-demo`和`kotlin-demo`示例项目中的`should_able_to_mock_new_object()`测试用例。 +完整代码示例见`java-demo`和`kotlin-demo`示例项目中的`should_mock_new_object()`测试用例。 #### 5. 在Mock方法中区分调用来源 @@ -157,7 +157,7 @@ private Data mockDemo() { } ``` -完整代码示例见`java-demo`和`kotlin-demo`示例项目中的`should_able_to_get_source_method_name()`和`should_able_to_get_test_case_name()`测试用例。 +完整代码示例见`java-demo`和`kotlin-demo`示例项目中的`should_get_source_method_name()`和`should_get_test_case_name()`测试用例。 #### 6. 验证Mock方法被调用的顺序和参数 diff --git a/testable-agent/src/test/java/com/alibaba/testable/agent/util/ClassUtilTest.java b/testable-agent/src/test/java/com/alibaba/testable/agent/util/ClassUtilTest.java index 04d8eda..4804486 100644 --- a/testable-agent/src/test/java/com/alibaba/testable/agent/util/ClassUtilTest.java +++ b/testable-agent/src/test/java/com/alibaba/testable/agent/util/ClassUtilTest.java @@ -7,12 +7,12 @@ import static org.junit.jupiter.api.Assertions.assertEquals; class ClassUtilTest { @Test - void should_able_to_convert_class_name() { + void should_convert_class_name() { assertEquals("Ljava/lang/String;", ClassUtil.toByteCodeClassName("java.lang.String")); } @Test - void should_able_to_fit_companion_class_name() { + void should_fit_companion_class_name() { assertEquals("com/intellij/rt/debugger/agent/CaptureAgent$ParamKeyProvider", ClassUtil.fitCompanionClassName("com/intellij/rt/debugger/agent/CaptureAgent$ParamKeyProvider")); assertEquals("com/alibaba/testable/demo/BlackBox", diff --git a/testable-agent/src/test/java/com/alibaba/testable/agent/util/CollectionUtilTest.java b/testable-agent/src/test/java/com/alibaba/testable/agent/util/CollectionUtilTest.java index 61b0ab5..a7e2a1e 100644 --- a/testable-agent/src/test/java/com/alibaba/testable/agent/util/CollectionUtilTest.java +++ b/testable-agent/src/test/java/com/alibaba/testable/agent/util/CollectionUtilTest.java @@ -7,7 +7,7 @@ import static org.junit.jupiter.api.Assertions.*; class CollectionUtilTest { @Test - void should_able_to_check_collection_contains_any_element() { + void should_check_collection_contains_any_element() { assertTrue(CollectionUtil.containsAny( CollectionUtil.listOf("a", "b"), CollectionUtil.listOf("b", "c") )); diff --git a/testable-agent/src/test/java/com/alibaba/testable/agent/util/MethodUtilTest.java b/testable-agent/src/test/java/com/alibaba/testable/agent/util/MethodUtilTest.java index be4b84a..f46b2e5 100644 --- a/testable-agent/src/test/java/com/alibaba/testable/agent/util/MethodUtilTest.java +++ b/testable-agent/src/test/java/com/alibaba/testable/agent/util/MethodUtilTest.java @@ -8,7 +8,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; class MethodUtilTest { @Test - void should_able_to_get_parameter_count() { + void should_get_parameter_count() { assertEquals(0, MethodUtil.getParameterTypes("()V").size()); assertEquals(1, MethodUtil.getParameterTypes("(Ljava/lang/String;)V").size()); assertEquals(6, MethodUtil.getParameterTypes("(Ljava/lang/String;IDLjava/lang/String;ZLjava/net/URL;)V").size()); @@ -17,13 +17,13 @@ class MethodUtilTest { } @Test - void should_able_to_extract_parameter() { + void should_extract_parameter() { assertEquals("", MethodUtil.extractParameters("()I")); assertEquals("Ljava/lang/String;", MethodUtil.extractParameters("(Ljava/lang/String;)I")); } @Test - void should_able_to_get_return_type() { + void should_get_return_type() { assertEquals("V", MethodUtil.getReturnType("(Ljava/lang/String;)V")); assertEquals("I", MethodUtil.getReturnType("(Ljava/lang/String;)I")); assertEquals("[I", MethodUtil.getReturnType("(Ljava/lang/String;)[I")); @@ -32,14 +32,14 @@ class MethodUtilTest { } @Test - void should_able_to_get_first_parameter() { + void should_get_first_parameter() { assertEquals("Ljava/lang/String;", MethodUtil.getFirstParameter("(Ljava/lang/String;Ljava/lang/Object;I)V")); assertEquals("Ljava/lang/String;", MethodUtil.getFirstParameter("(Ljava/lang/String;)V")); assertEquals("", MethodUtil.getFirstParameter("()V")); } @Test - void should_able_to_convert_bytecode_parameters() { + void should_convert_bytecode_parameters() { assertEquals("", PrivateAccessor.invokeStatic(MethodUtil.class, "toJavaParameterDesc", "")); assertEquals("void", PrivateAccessor.invokeStatic(MethodUtil.class, "toJavaParameterDesc", "V")); assertEquals("int, long", PrivateAccessor.invokeStatic(MethodUtil.class, "toJavaParameterDesc", "IJ")); diff --git a/testable-agent/src/test/java/com/alibaba/testable/agent/util/StringUtilTest.java b/testable-agent/src/test/java/com/alibaba/testable/agent/util/StringUtilTest.java index f894eff..1185167 100644 --- a/testable-agent/src/test/java/com/alibaba/testable/agent/util/StringUtilTest.java +++ b/testable-agent/src/test/java/com/alibaba/testable/agent/util/StringUtilTest.java @@ -7,7 +7,7 @@ import static org.junit.jupiter.api.Assertions.*; class StringUtilTest { @Test - void should_able_to_repeat_text() { + void should_repeat_text() { assertEquals("", StringUtil.repeat("abc", 0)); assertEquals("abc", StringUtil.repeat("abc", 1)); assertEquals("abcabcabc", StringUtil.repeat("abc", 3)); diff --git a/testable-core/src/main/java/com/alibaba/testable/core/accessor/PrivateAccessor.java b/testable-core/src/main/java/com/alibaba/testable/core/accessor/PrivateAccessor.java index 78f090d..803c319 100644 --- a/testable-core/src/main/java/com/alibaba/testable/core/accessor/PrivateAccessor.java +++ b/testable-core/src/main/java/com/alibaba/testable/core/accessor/PrivateAccessor.java @@ -15,6 +15,8 @@ public class PrivateAccessor { private static final String KOTLIN_COMPANION_FIELD = "Companion"; + private PrivateAccessor() {} + /** * 读取任意类的私有字段 * @param ref 目标对象 diff --git a/testable-core/src/main/java/com/alibaba/testable/core/exception/ClassConstructionException.java b/testable-core/src/main/java/com/alibaba/testable/core/exception/ClassConstructionException.java new file mode 100644 index 0000000..fedfa79 --- /dev/null +++ b/testable-core/src/main/java/com/alibaba/testable/core/exception/ClassConstructionException.java @@ -0,0 +1,26 @@ +package com.alibaba.testable.core.exception; + +import java.lang.reflect.InvocationTargetException; + +/** + * @author flin + */ +public class ClassConstructionException extends RuntimeException { + + public ClassConstructionException(String message) { + super(message); + } + + public ClassConstructionException(String message, Throwable cause) { + super(message, cause); + } + + private static Throwable getRootCause(Throwable cause) { + if (cause instanceof InvocationTargetException) { + return ((InvocationTargetException)cause).getTargetException(); + } else { + return cause; + } + } + +} diff --git a/testable-core/src/main/java/com/alibaba/testable/core/tool/OmniAccessor.java b/testable-core/src/main/java/com/alibaba/testable/core/tool/OmniAccessor.java index df8d617..11dc165 100644 --- a/testable-core/src/main/java/com/alibaba/testable/core/tool/OmniAccessor.java +++ b/testable-core/src/main/java/com/alibaba/testable/core/tool/OmniAccessor.java @@ -8,6 +8,7 @@ import java.lang.reflect.Array; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import static com.alibaba.testable.core.constant.ConstPool.SLASH; @@ -27,26 +28,28 @@ public class OmniAccessor { private static final String BRACKET_START = "["; private static final String BRACKET_END = "]"; + private OmniAccessor() {} + /** * 获取第一个符合搜索路径的成员 - * @param target 目标对象 + * + * @param target 目标对象 * @param queryPath 搜索路径 - * @param clazz 目标成员类型 * @return 返回目标成员,若不存在则返回null */ - public static T getFirst(Object target, String queryPath, Class clazz) { - List values = get(target, queryPath, clazz); - return values.isEmpty() ? null : values.get(0); + public static T getFirst(Object target, String queryPath) { + T[] values = get(target, queryPath); + return values.length == 0 ? null : values[0]; } /** * 获取所有符合搜索路径的成员 - * @param target 目标对象 + * + * @param target 目标对象 * @param queryPath 搜索路径 - * @param clazz 目标成员类型 * @return 返回所有匹配的成员 */ - public static List get(Object target, String queryPath, Class clazz) { + public static T[] get(Object target, String queryPath) { List values = new ArrayList(); for (String memberPath : MEMBER_INDEXES.getOrElse(target.getClass(), generateMemberIndex(target.getClass()))) { if (memberPath.matches(toPattern(queryPath))) { @@ -62,14 +65,15 @@ public class OmniAccessor { } } } - return values; + return (T[])values.toArray(); } /** * 为符合搜索路径的成员赋值 - * @param target 目标对象 + * + * @param target 目标对象 * @param queryPath 搜索路径 - * @param value 新的值 + * @param value 新的值 * @return 实际影响的成员个数 */ public static int set(Object target, String queryPath, Object value) { @@ -97,6 +101,9 @@ public class OmniAccessor { } private static List generateMemberIndex(String basePath, Class clazz) { + if (clazz.isEnum()) { + return Collections.emptyList(); + } List fields = TypeUtil.getAllFields(clazz); List paths = new ArrayList(); for (Field f : fields) { @@ -155,12 +162,11 @@ public class OmniAccessor { private static Object getByPath(Object target, String memberPath, String queryPath) throws NoSuchFieldException, IllegalAccessException { String[] memberSegments = memberPath.split(SLASH); - String[] querySegments = queryPath.split(SLASH); + String[] querySegments = calculateFullQueryPath(queryPath.split(SLASH), memberSegments); Object obj = target; String name; int nth; Field field; - assert memberSegments.length == querySegments.length; for (int i = 0; i < memberSegments.length; i++) { name = memberSegments[i].substring(0, memberSegments[i].indexOf(BRACE_START)); nth = extraIndexFromQuery(querySegments[i]); @@ -176,6 +182,21 @@ public class OmniAccessor { return obj; } + private static String[] calculateFullQueryPath(String[] querySegments, String[] memberSegments) { + assert memberSegments.length >= querySegments.length; + ; + if (memberSegments.length > querySegments.length) { + String[] fullQuerySegments = new String[memberSegments.length]; + for (int i = 0; i < querySegments.length; i++) { + fullQuerySegments[i] = ""; + } + System.arraycopy(querySegments, 0, fullQuerySegments, querySegments.length, + memberSegments.length - querySegments.length); + return fullQuerySegments; + } + return querySegments; + } + private static void setByPathSegment(Object target, String memberSegment, String querySegment, Object value) throws IllegalAccessException { String name = memberSegment.substring(0, memberSegment.indexOf(BRACE_START)); diff --git a/testable-core/src/main/java/com/alibaba/testable/core/tool/OmniConstructor.java b/testable-core/src/main/java/com/alibaba/testable/core/tool/OmniConstructor.java index b9afea8..3101a30 100644 --- a/testable-core/src/main/java/com/alibaba/testable/core/tool/OmniConstructor.java +++ b/testable-core/src/main/java/com/alibaba/testable/core/tool/OmniConstructor.java @@ -1,5 +1,6 @@ package com.alibaba.testable.core.tool; +import com.alibaba.testable.core.exception.ClassConstructionException; import com.alibaba.testable.core.model.Null; import com.alibaba.testable.core.util.TypeUtil; @@ -10,6 +11,8 @@ import java.lang.reflect.*; */ public class OmniConstructor { + private OmniConstructor() {} + public static T newInstance(Class clazz) { try { if (clazz.isPrimitive()) { @@ -25,15 +28,15 @@ public class OmniConstructor { } return newObject(clazz); } catch (NoSuchMethodException e) { - return null; + throw new ClassConstructionException("Failed to find constructor", e); } catch (IllegalAccessException e) { - return null; - } catch (InstantiationException e) { - return null; + throw new ClassConstructionException("Failed to access constructor", e); } catch (InvocationTargetException e) { - return null; + throw new ClassConstructionException("Failed to invoke constructor", e); + } catch (InstantiationException e) { + throw new ClassConstructionException("Failed to complete construction", e); } catch (ClassCastException e) { - return null; + throw new ClassConstructionException("Unexpected type", e); } } @@ -88,15 +91,6 @@ public class OmniConstructor { return null; } - private static boolean isJavaAgentEnabled(Class clazz) { - try { - clazz.getDeclaredConstructor(Null.class); - } catch (NoSuchMethodException e) { - return false; - } - return true; - } - private static Object newInstance(Constructor constructor) throws InstantiationException, IllegalAccessException, InvocationTargetException { Class[] types = constructor.getParameterTypes(); diff --git a/testable-core/src/test/java/com/alibaba/testable/core/tool/OmniAccessorTest.java b/testable-core/src/test/java/com/alibaba/testable/core/tool/OmniAccessorTest.java index 30e2c80..5a92452 100644 --- a/testable-core/src/test/java/com/alibaba/testable/core/tool/OmniAccessorTest.java +++ b/testable-core/src/test/java/com/alibaba/testable/core/tool/OmniAccessorTest.java @@ -33,24 +33,24 @@ class OmniAccessorTest { @Test void should_match_pattern() { - assertTrue("abc{Abc}".matches("abc\\{[^}]+\\}")); - assertTrue("abc{Abc}".matches("[^{]+\\{Abc\\}")); - assertTrue("abc{Abc[]}/xyz{Xyz[]}".matches("[^{]+\\{Abc\\[\\]\\}/[^{]+\\{Xyz\\[\\]\\}")); - assertTrue("abc{Abc}/xyz{Xyz}/demo{Demo}".matches("abc\\{[^}]+\\}/[^{]+\\{Xyz\\}/demo\\{[^}]+\\}")); + assertTrue("/abc{Abc}".matches(".*/abc\\{[^}]+\\}")); + assertTrue("/abc{Abc}".matches(".*/[^{]+\\{Abc\\}")); + assertTrue("/abc{Abc[]}/xyz{Xyz[]}".matches(".*/[^{]+\\{Abc\\[\\]\\}/[^{]+\\{Xyz\\[\\]\\}")); + assertTrue("/abc{Abc}/xyz{Xyz}/demo{Demo}".matches(".*/abc\\{[^}]+\\}/[^{]+\\{Xyz\\}/demo\\{[^}]+\\}")); } @Test void should_to_pattern() { - assertEquals("", PrivateAccessor.invokeStatic(OmniAccessor.class, "toPattern", "")); - assertEquals("abc\\{[^}]+\\}", PrivateAccessor.invokeStatic(OmniAccessor.class, "toPattern", "abc")); - assertEquals("[^{]+\\{Abc\\}", PrivateAccessor.invokeStatic(OmniAccessor.class, "toPattern", "{Abc}")); - assertEquals("abc\\{[^}]+\\}/xyz\\{[^}]+\\}", PrivateAccessor.invokeStatic(OmniAccessor.class, "toPattern", "abc/xyz")); - assertEquals("[^{]+\\{Abc\\}/xyz\\{[^}]+\\}", PrivateAccessor.invokeStatic(OmniAccessor.class, "toPattern", "{Abc}/xyz")); - assertEquals("abc\\{[^}]+\\}/[^{]+\\{Xyz\\}", PrivateAccessor.invokeStatic(OmniAccessor.class, "toPattern", "abc/{Xyz}")); - assertEquals("[^{]+\\{Abc\\}/[^{]+\\{Xyz\\}", PrivateAccessor.invokeStatic(OmniAccessor.class, "toPattern", "{Abc}/{Xyz}")); - assertEquals("[^{]+\\{Abc\\[\\]\\}/[^{]+\\{Xyz\\[\\]\\}", PrivateAccessor.invokeStatic(OmniAccessor.class, "toPattern", "{Abc[]}/{Xyz[]}")); - assertEquals("abc\\{[^}]+\\}/[^{]+\\{Xyz\\[\\]\\}", PrivateAccessor.invokeStatic(OmniAccessor.class, "toPattern", "abc[1]/{Xyz[]}[2]")); - assertEquals("abc\\{[^}]+\\}/[^{]+\\{Xyz\\}/demo\\{[^}]+\\}", PrivateAccessor.invokeStatic(OmniAccessor.class, "toPattern", "abc/{Xyz}/demo")); + assertEquals(".*/", PrivateAccessor.invokeStatic(OmniAccessor.class, "toPattern", "")); + assertEquals(".*/abc\\{[^}]+\\}", PrivateAccessor.invokeStatic(OmniAccessor.class, "toPattern", "abc")); + assertEquals(".*/[^{]+\\{Abc\\}", PrivateAccessor.invokeStatic(OmniAccessor.class, "toPattern", "{Abc}")); + assertEquals(".*/abc\\{[^}]+\\}/xyz\\{[^}]+\\}", PrivateAccessor.invokeStatic(OmniAccessor.class, "toPattern", "abc/xyz")); + assertEquals(".*/[^{]+\\{Abc\\}/xyz\\{[^}]+\\}", PrivateAccessor.invokeStatic(OmniAccessor.class, "toPattern", "{Abc}/xyz")); + assertEquals(".*/abc\\{[^}]+\\}/[^{]+\\{Xyz\\}", PrivateAccessor.invokeStatic(OmniAccessor.class, "toPattern", "abc/{Xyz}")); + assertEquals(".*/[^{]+\\{Abc\\}/[^{]+\\{Xyz\\}", PrivateAccessor.invokeStatic(OmniAccessor.class, "toPattern", "{Abc}/{Xyz}")); + assertEquals(".*/[^{]+\\{Abc\\[\\]\\}/[^{]+\\{Xyz\\[\\]\\}", PrivateAccessor.invokeStatic(OmniAccessor.class, "toPattern", "{Abc[]}/{Xyz[]}")); + assertEquals(".*/abc\\{[^}]+\\}/[^{]+\\{Xyz\\[\\]\\}", PrivateAccessor.invokeStatic(OmniAccessor.class, "toPattern", "abc[1]/{Xyz[]}[2]")); + assertEquals(".*/abc\\{[^}]+\\}/[^{]+\\{Xyz\\}/demo\\{[^}]+\\}", PrivateAccessor.invokeStatic(OmniAccessor.class, "toPattern", "abc/{Xyz}/demo")); } @Test @@ -71,21 +71,33 @@ class OmniAccessorTest { assertEquals("xyz", PrivateAccessor.invokeStatic(OmniAccessor.class, "toChild", "/abc/def/xyz")); } + @Test + void should_get_full_query_segments() { + String[] querySegments = new String[] { "c", "d" }; + String[] memberSegments = new String[] { "a{A}", "b{B}", "c{C}", "d{D}" }; + String[] fullQuerySegments = PrivateAccessor.invokeStatic(OmniAccessor.class, "calculateFullQueryPath", querySegments, memberSegments); + assertEquals(4, fullQuerySegments.length); + assertEquals("", fullQuerySegments[0]); + assertEquals("", fullQuerySegments[1]); + assertEquals("c", fullQuerySegments[2]); + assertEquals("d", fullQuerySegments[3]); + } + @Test void should_get_by_path() { DemoParent parent = prepareParentObject(); - Object obj = PrivateAccessor.invokeStatic(OmniAccessor.class, "getByPath", parent, "c{DemoChild}/gc{DemoGrandChild}", "c/gc"); + Object obj = PrivateAccessor.invokeStatic(OmniAccessor.class, "getByPath", parent, "/c{DemoChild}/gc{DemoGrandChild}", "c/gc"); assertTrue(obj instanceof DemoGrandChild); assertEquals(0, ((DemoGrandChild)obj).get()); PrivateAccessor.set(parent.c, "gcs", new DemoGrandChild[] { new DemoGrandChild(4), new DemoGrandChild(6) }); - obj = PrivateAccessor.invokeStatic(OmniAccessor.class, "getByPath", parent, "c{DemoChild}/gcs{DemoGrandChild[]}", "c/gcs"); + obj = PrivateAccessor.invokeStatic(OmniAccessor.class, "getByPath", parent, "/c{DemoChild}/gcs{DemoGrandChild[]}", "c/gcs"); assertTrue(obj instanceof DemoGrandChild[]); assertEquals(2, ((DemoGrandChild[])obj).length); - obj = PrivateAccessor.invokeStatic(OmniAccessor.class, "getByPath", parent, "c{DemoChild}/gcs{DemoGrandChild[]}", "c/gcs[1]"); + obj = PrivateAccessor.invokeStatic(OmniAccessor.class, "getByPath", parent, "/c{DemoChild}/gcs{DemoGrandChild[]}", "c/gcs[1]"); assertTrue(obj instanceof DemoGrandChild); assertEquals(6, ((DemoGrandChild)obj).get()); parent.cs = new DemoChild[] { null, prepareChildObject() }; - obj = PrivateAccessor.invokeStatic(OmniAccessor.class, "getByPath", parent, "cs{DemoChild[]}/gcs{DemoGrandChild[]}/i{int}", "c[1]/gcs[1]/i"); + obj = PrivateAccessor.invokeStatic(OmniAccessor.class, "getByPath", parent, "/cs{DemoChild[]}/gcs{DemoGrandChild[]}/i{int}", "c[1]/gcs[1]/i"); assertEquals(3, obj); } diff --git a/testable-core/src/test/java/com/alibaba/testable/core/util/MockAssociationUtilTest.java b/testable-core/src/test/java/com/alibaba/testable/core/util/MockAssociationUtilTest.java index 99d7367..91057a4 100644 --- a/testable-core/src/test/java/com/alibaba/testable/core/util/MockAssociationUtilTest.java +++ b/testable-core/src/test/java/com/alibaba/testable/core/util/MockAssociationUtilTest.java @@ -8,7 +8,7 @@ import static org.junit.jupiter.api.Assertions.*; class MockAssociationUtilTest { @Test - void should_able_to_associate_by_inner_mock_class() { + void should_associate_by_inner_mock_class() { assertTrue((Boolean)PrivateAccessor.invokeStatic(MockAssociationUtil.class, "isAssociatedByInnerMockClass", "com.alibaba.testable.DemoTest", "com.alibaba.testable.DemoTest$Mock")); assertFalse((Boolean)PrivateAccessor.invokeStatic(MockAssociationUtil.class, "isAssociatedByInnerMockClass", @@ -16,7 +16,7 @@ class MockAssociationUtilTest { } @Test - void should_able_to_associate_by_outer_mock_class() { + void should_associate_by_outer_mock_class() { assertTrue((Boolean)PrivateAccessor.invokeStatic(MockAssociationUtil.class, "isAssociatedByOuterMockClass", "com.alibaba.testable.DemoTest", "com.alibaba.testable.DemoMock")); assertFalse((Boolean)PrivateAccessor.invokeStatic(MockAssociationUtil.class, "isAssociatedByOuterMockClass", diff --git a/testable-processor/src/test/java/com/alibaba/testable/processor/util/StringUtilTest.java b/testable-processor/src/test/java/com/alibaba/testable/processor/util/StringUtilTest.java index c7c1935..fe8218f 100644 --- a/testable-processor/src/test/java/com/alibaba/testable/processor/util/StringUtilTest.java +++ b/testable-processor/src/test/java/com/alibaba/testable/processor/util/StringUtilTest.java @@ -10,7 +10,7 @@ import static org.junit.jupiter.api.Assertions.*; class StringUtilTest { @Test - void should_able_to_join_string() { + void should_join_string() { List list = new ArrayList(4); list.add("a"); list.add("b");