mirror of
https://github.com/alibaba/testable-mock.git
synced 2025-01-25 20:00:17 +08:00
67 lines
3.6 KiB
Markdown
67 lines
3.6 KiB
Markdown
|
使用MockWith注解
|
|||
|
---
|
|||
|
|
|||
|
`@MockWith`注释的功能是为测试显式指定Mock容器,通常用于测试类或Mock容器类没有在标准约定位置的情况,以下列举几种典型使用场景。
|
|||
|
|
|||
|
### 1. 非标准位置的Mock容器类
|
|||
|
|
|||
|
`TestableMock`会依次在以下两个位置寻找Mock容器:
|
|||
|
|
|||
|
- 测试类中名为`Mock`的静态内部类(譬如原类型是`Demo`,测试类是`DemoTest`,Mock容器类为`DemoTest.Mock`)
|
|||
|
- 同包路径下寻找名为`被测类+Mock`的外部类(譬如原类型是`Demo`,测试类是`DemoTest`,Mock容器类为`DemoMock`)
|
|||
|
|
|||
|
倘若实际要使用的Mock容器类不在这两个位置,就需要在测试类上使用`@MockWith`注释了。一般来说,造成Mock容器类不在默认位置的原因可能有两种:复用Mock容器、集中管理Mock容器。
|
|||
|
|
|||
|
当对一批功能近似的类型进行测试的时候,由于需要进行Mock的外部调用基本一致,可以将这些类型所需的所有Mock方法集中写在一个Mock容器类里,然后让相关测试类共同引用这个公共Mock容器。详见[复用Mock类与方法](zh-cn/doc/mock-method-reusing.md)文档。
|
|||
|
|
|||
|
另一种情况是开发者希望将Mock方法的定义与测试类本身分开,以便进行集中管理(或规避某些扫描工具的路径规则),譬如形成下面这种目录结构:
|
|||
|
|
|||
|
```
|
|||
|
src/
|
|||
|
main/
|
|||
|
com/
|
|||
|
demo/
|
|||
|
service/
|
|||
|
DemoService.java
|
|||
|
test/
|
|||
|
com/
|
|||
|
demo/
|
|||
|
service/
|
|||
|
DemoServiceTest.java
|
|||
|
mock/
|
|||
|
service/
|
|||
|
DemoServiceMock.java
|
|||
|
```
|
|||
|
|
|||
|
此时就需要在测试类上显式的指定相应的Mock容器类了,这种场景在实际情况中比较少见。
|
|||
|
|
|||
|
### 2. 非标准位置的测试类
|
|||
|
|
|||
|
`TestableMock`在建立“被测类”、“测试类”、“Mock容器类”之间关联的过程中,为了识别被测类的位置,约定测试类应当与被测类在相同的包路径,且名称为`被测类+Test`。当实际情况不符合这种约定的时候,就需要通过在**被测类**上添加`@MockWith`注解来显式的建立关联。例如:
|
|||
|
|
|||
|
```java
|
|||
|
@MockWith(ServiceTest.Mock.class)
|
|||
|
public class DemoService {
|
|||
|
...
|
|||
|
}
|
|||
|
|
|||
|
public class ServiceTest {
|
|||
|
public static class Mock extends BasicMock {
|
|||
|
...
|
|||
|
}
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
> 注意:
|
|||
|
> 1. `@MockWith`注解通常是使用在测试类上,但这种情况下需要用在被测类上
|
|||
|
> 2. `@MockWith`指向的目标始终是Mock容器类,而不是测试类
|
|||
|
> 3. `@MockWith`默认使用被注解类名字的尾缀判断当前类是被测类(名字非`Test`结尾)还是测试类(名字`Test`结尾),若遇到不符合此规则的类型,应使用注解的`treatAs`参数显式的指定(`ClassType.SourceClass`-被测类/`ClassType.TestClass`-测试类)
|
|||
|
|
|||
|
更进一步来说,若出现测试类与Mock容器类均不在约定位置的时候,则需要同时在**测试类**与**被测类**上都使用`@MockWith`指向同一个Mock容器类来建立三者的关联,但这种场景在实际运用中很少会遇到。
|
|||
|
|
|||
|
### 3. 使用不包含Mock方法的Mock容器类
|
|||
|
|
|||
|
为了加快搜索Mock容器类的速度,在扫描过程中,`TestableMock`只会将自身定义有Mock方法(包含`@MockMethod`或`@MockMockConstructor`注解的方法)以及明确被`@MockWith`指向的类识别为有效的Mock容器,而不会去遍历其父类。
|
|||
|
|
|||
|
对于某些特殊情况,譬如希望将实际Mock方法均定义在父类,实际使用的子容器仅仅重载父类的某些特定方法,此时即使Mock容器类的位置符合约定,为了能够被识别,依然应该在相应的测试类上增加对Mock容器类的`@MockWith`引用。
|