mirror of
https://github.com/alibaba/testable-mock.git
synced 2025-02-10 11:51:09 +08:00
static constraint will be remove in future
This commit is contained in:
parent
a6b289e136
commit
3df95db607
@ -9,13 +9,13 @@ Compared with the class-granularity mocking practices of existing mock tools, `T
|
||||
|
||||
> **Mock convention**:
|
||||
> - The name of the test class should be `<NameOfClassUnderTest> + Test` (and in the same package path), which is usually the by-default naming convention of Java project managed by `Maven` or `Gradle`. This constraint may be relaxed or removed in future versions of `TestableMock`.
|
||||
> - Methods that is decorated by `@MockMethod` or `@MockContructor` annotations will be automatically modified to `static` methods during runtime. Please do not access any non-`static` members in these methods. To be on the safe side, it is recommended to define these methods directly as `static`. In future versions, a compile-time warning will be added to non-`static` declared mock methods.
|
||||
> - Do NOT access any non-`static` members in mock methods. Currently, methods that is decorated by `@MockMethod` or `@MockContructor` annotations will be automatically modified to `static` methods during runtime. In future versions, this constraint will be removed.
|
||||
|
||||
The detail mock method definition convention is as follows:
|
||||
|
||||
#### 1. Mock method calls of any class
|
||||
|
||||
Define an ordinary method annotated with `@MockMethod` in the test class with exactly the same signature (name, parameter, and return value type) as the method to be mocked (`static` declaration is recommended), and then add an extra parameter as the first parameter of method, with the same type as the object that the method originally belongs to.
|
||||
Define an ordinary method annotated with `@MockMethod` in the test class with exactly the same signature (name, parameter, and return value type) as the method to be mocked, and then add an extra parameter as the first parameter of method, with the same type as the object that the method originally belongs to.
|
||||
|
||||
At this time, all invocations to that original method in the class under test will be automatically replaced with invocations to the above-mentioned mock method when the unit test is running.
|
||||
|
||||
@ -29,7 +29,7 @@ For example, there is a call to `"anything".substring(1, 2)` in the class under
|
||||
// Adds a `String` type parameter to the first position the mock method parameter list (parameter name is arbitrary)
|
||||
// This parameter can be used to get the value and context of the actual invoker at runtime
|
||||
@MockMethod
|
||||
private static String substring(String self, int i, int j) {
|
||||
private String substring(String self, int i, int j) {
|
||||
return "sub_string";
|
||||
}
|
||||
```
|
||||
@ -40,7 +40,7 @@ The following example shows the usage of the `targetMethod` parameter, and its e
|
||||
// Use `targetMethod` to specify the name of the method that needs to be mocked
|
||||
// The method itself can now be named arbitrarily, but the method parameters still need to follow the same matching rules
|
||||
@MockMethod(targetMethod = "substring")
|
||||
private static String use_any_mock_method_name(String self, int i, int j) {
|
||||
private String use_any_mock_method_name(String self, int i, int j) {
|
||||
return "sub_string";
|
||||
}
|
||||
```
|
||||
@ -59,7 +59,7 @@ For example, there is a private method with the signature `String innerFunc(Stri
|
||||
// The type to test is `DemoMock`
|
||||
// So when defining the mock method, add a parameter of type `DemoMock` to the first position of parameter list (the name is arbitrary)
|
||||
@MockMethod
|
||||
private static String innerFunc(DemoMock self, String text) {
|
||||
private String innerFunc(DemoMock self, String text) {
|
||||
return "mock_" + text;
|
||||
}
|
||||
```
|
||||
@ -77,7 +77,7 @@ For example, if the static method `secretBox()` of the `BlackBox` type is invoke
|
||||
// When defining the mock method, add a parameter of type `BlackBox` to the first position parameter list (the name is arbitrary)
|
||||
// This parameter is only used to identify the target type, the actual incoming value will always be `null`
|
||||
@MockMethod
|
||||
private static BlackBox secretBox(BlackBox ignore) {
|
||||
private BlackBox secretBox(BlackBox ignore) {
|
||||
return new BlackBox("not_secret_box");
|
||||
}
|
||||
```
|
||||
@ -86,7 +86,7 @@ For complete code examples, see the `should_able_to_mock_static_method()` test c
|
||||
|
||||
#### 4. Mock `new` operation of any type
|
||||
|
||||
Define an ordinary method annotated with `@MockContructor` in the test class (`static` declaration is recommended), make the return value type of the method the type of the object to be created, and the method parameters are exactly the same as the constructor parameters to be mocked, the method name is arbitrary.
|
||||
Define an ordinary method annotated with `@MockContructor` in the test class, make the return value type of the method the type of the object to be created, and the method parameters are exactly the same as the constructor parameters to be mocked, the method name is arbitrary.
|
||||
|
||||
At this time, all operations in the class under test that use `new` to create the specified class (and use the constructor that is consistent with the mock method parameters) will be replaced with calls to the custom method.
|
||||
|
||||
@ -96,7 +96,7 @@ For example, if there is a call to `new BlackBox("something")` in the class unde
|
||||
// The signature of the constructor to be mocked is `BlackBox(String)`
|
||||
// No need to add additional parameters to the mock method parameter list, and the name of the mock method is arbitrary
|
||||
@MockContructor
|
||||
private static BlackBox createBlackBox(String text) {
|
||||
private BlackBox createBlackBox(String text) {
|
||||
return new BlackBox("mock_" + text);
|
||||
}
|
||||
```
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
> **Mock约定**:
|
||||
> - 测试类与被测类的包路径应相同,且名称为`被测类名+Test`。通常采用`Maven`或`Gradle`构建的Java项目均符合这种惯例。此约定在未来的`TestableMock`版本中可能会被放宽或去除(请关注[Issue-12](https://github.com/alibaba/testable-mock/issues/12))。
|
||||
> - 包含`@MockMethod`或`@MockContructor`注解的方法会在运行期被自动修改为静态(`static`)方法,请勿在其中访问任何非静态成员。为保险起见,建议将这些方法直接定义为静态方法。在未来版本中会增加对定义非静态Mock方法的编译期警告。
|
||||
> - 请勿在Mock方法的定义中访问任何非静态成员。当前包含`@MockMethod`或`@MockContructor`注解的方法会在运行期被自动修改为静态(`static`)方法。此约定在未来的版本中将被去除,请留意相关更新。
|
||||
|
||||
具体的Mock方法定义约定如下:
|
||||
|
||||
@ -29,7 +29,7 @@
|
||||
// 则Mock方法签名在其参数列表首位增加一个类型为`String`的参数(名字随意)
|
||||
// 此参数可用于获得当时的实际调用者的值和上下文
|
||||
@MockMethod
|
||||
private static String substring(String self, int i, int j) {
|
||||
private String substring(String self, int i, int j) {
|
||||
return "sub_string";
|
||||
}
|
||||
```
|
||||
@ -40,7 +40,7 @@ private static String substring(String self, int i, int j) {
|
||||
// 使用`targetMethod`指定需Mock的方法名
|
||||
// 此方法本身现在可以随意命名,但方法参数依然需要遵循相同的匹配规则
|
||||
@MockMethod(targetMethod = "substring")
|
||||
private static String use_any_mock_method_name(String self, int i, int j) {
|
||||
private String use_any_mock_method_name(String self, int i, int j) {
|
||||
return "sub_string";
|
||||
}
|
||||
```
|
||||
@ -53,13 +53,13 @@ private static String use_any_mock_method_name(String self, int i, int j) {
|
||||
|
||||
操作方法与前一种情况相同,Mock方法的第一个参数类型需与被测类相同,即可实现对被测类自身(不论是公有或私有)成员方法的覆写。
|
||||
|
||||
例如,被测类中有一个签名为`String innerFunc(String)`的私有方法(建议使用静态方法),我们希望在测试的时候将它替换掉,则只需在测试类定义如下方法:
|
||||
例如,被测类中有一个签名为`String innerFunc(String)`的私有方法,我们希望在测试的时候将它替换掉,则只需在测试类定义如下方法:
|
||||
|
||||
```java
|
||||
// 被测类型是`DemoMock`
|
||||
// 因此在定义Mock方法时,在目标方法参数首位加一个类型为`DemoMock`的参数(名字随意)
|
||||
@MockMethod
|
||||
private static String innerFunc(DemoMock self, String text) {
|
||||
private String innerFunc(DemoMock self, String text) {
|
||||
return "mock_" + text;
|
||||
}
|
||||
```
|
||||
@ -77,7 +77,7 @@ private static String innerFunc(DemoMock self, String text) {
|
||||
// 在定义Mock方法时,在目标方法参数首位加一个类型为`BlackBox`的参数(名字随意)
|
||||
// 此参数仅用于标识目标类型,实际传入值将始终为`null`
|
||||
@MockMethod
|
||||
private static BlackBox secretBox(BlackBox ignore) {
|
||||
private BlackBox secretBox(BlackBox ignore) {
|
||||
return new BlackBox("not_secret_box");
|
||||
}
|
||||
```
|
||||
@ -86,7 +86,7 @@ private static BlackBox secretBox(BlackBox ignore) {
|
||||
|
||||
#### 4. 覆写任意类的new操作
|
||||
|
||||
在测试类里定义一个有`@MockContructor`注解的普通方法(建议使用静态方法),使该方法返回值类型为要被创建的对象类型,且方法参数与要Mock的构造函数参数完全一致,方法名称随意。
|
||||
在测试类里定义一个有`@MockContructor`注解的普通方法,使该方法返回值类型为要被创建的对象类型,且方法参数与要Mock的构造函数参数完全一致,方法名称随意。
|
||||
|
||||
此时被测类中所有用`new`创建指定类的操作(并使用了与Mock方法参数一致的构造函数)将被替换为对该自定义方法的调用。
|
||||
|
||||
@ -96,7 +96,7 @@ private static BlackBox secretBox(BlackBox ignore) {
|
||||
// 要覆写的构造函数签名为`BlackBox(String)`
|
||||
// 无需在Mock方法参数列表增加额外参数,Mock方法的名称随意起
|
||||
@MockContructor
|
||||
private static BlackBox createBlackBox(String text) {
|
||||
private BlackBox createBlackBox(String text) {
|
||||
return new BlackBox("mock_" + text);
|
||||
}
|
||||
```
|
||||
|
@ -51,7 +51,7 @@ public class LogUtil {
|
||||
}
|
||||
|
||||
public static void error(String msg, Object... args) {
|
||||
System.err.println(String.format("[FAIL] " + msg, args));
|
||||
System.err.println(String.format("[ERROR] " + msg, args));
|
||||
}
|
||||
|
||||
public static void enableDiagnose(boolean enable) {
|
||||
|
Loading…
Reference in New Issue
Block a user