https://github.com/sayi/testpie
:shallow_pan_of_food: 一种简单有效的单元测试方式
https://github.com/sayi/testpie
json junit mock mockito unittest yaml
Last synced: about 2 months ago
JSON representation
:shallow_pan_of_food: 一种简单有效的单元测试方式
- Host: GitHub
- URL: https://github.com/sayi/testpie
- Owner: Sayi
- License: apache-2.0
- Created: 2020-01-13T12:09:44.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2020-01-13T16:26:25.000Z (over 6 years ago)
- Last Synced: 2025-02-28T22:19:47.404Z (over 1 year ago)
- Topics: json, junit, mock, mockito, unittest, yaml
- Language: Java
- Homepage:
- Size: 27.3 KB
- Stars: 0
- Watchers: 3
- Forks: 1
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# TestPie
* :round_pushpin: **加载测试数据(JSON、YAML或其它格式),by** `@PieData`
* :clapper: **隔离Mock code和UnitTest code,by** `@MockPrimay` or `@MockProvider`
## 依赖
### Requirements
* JUnit 5
* Mockito(可选,如果需要使用mock功能)
### Gradle
```groovy
testImplementation "com.deepoove:testpie:0.0.1"
```
### Maven
```xml
com.deepoove
testpie
0.0.1
test
```
## `@PieData`:加载数据
### 方式一、`Pie.initAnnotations(this)`
**1). 准备测试数据user.json**
```json
{
"phone": 12306,
"name": "Sayi",
"age": 10
}
```
**2). 加载数据**
```java
@PieData(value = "/pie/user.json")
private User user;
public PieTest() {
Pie.initAnnotations(this);
}
@Test
public void testPieData() {
assertNotNull(user);
}
```
### 方式二、`PieExtension`代替`Pie.initAnnotations`:
```java
@ExtendWith(PieExtension.class)
public class PieExtensionTest {
@PieData(value = "/pie/user.json")
private User user;
@Test
public void testPieData() {
assertNotNull(user);
assertEquals(user.getPhone(), 12306);
}
}
```
### 扩展:使用`YamlConverter`加载yml数据
```java
@ExtendWith(PieExtension.class)
public class YamlConverterTest {
@PieData(value = "/yaml/user.yml", converter = YamlConverter.class)
private User user;
@Test
public void testPieDataByYaml() {
assertNotNull(user);
assertEquals(user.getPhone(), 12306);
}
}
```
### 扩展:自定义数据格式转化器
```java
public class GsonJsonConverter implements Converter {
@Override
public Object convert(String source, TypeContext context) {
Gson gson = new Gson();
return gson.fromJson(source, context.getType());
}
}
```
## `@MockPrimay`:为某个对象提供mock
一个对象的Mock功能可以被**快速构造**和**复用**,通过一个独立的类提供对象的所有Mock功能,这个类称为:该对象的Mock类,就像这样:
```java
Supplier mock = new UserServiceMock();
UserService userService = mock.get();
```
与这段代码等价的功能是TestPie提供了与Mockito集成的注解`@MockPrimay`来快速构造一个具有Mock功能的对象。
### 方式一、使用`@MockPrimay`
1). 创建一个单独的**对象Mock类**定义具体Mock功能
```java
public class UserServiceMock implements Consumer {
@PieData("/pie/list_user_.json")
private List userList;
public UserServiceMock() {
// 加载数据
Pie.initAnnotations(this);
}
@Override
public void accept(UserService userService) {
// 处理Mock功能
given(userService.findAll()).willReturn(userList);
given(userService.delete(1590000)).willReturn(false);
given(userService.delete(1581111)).willReturn(true);
}
}
```
2). 使用`@MockPrimay`快速初始化Mock对象
```java
@Mock(lenient = true)
@MockPrimary(UserServiceMock.class)
private UserService userService;
public PieMockitoTest() {
// first mockito
MockitoAnnotations.initMocks(this);
// the testpie
Pie.initAnnotations(this);
}
@Test
public void testPieData() {
assertFalse(userService.delete(1590000));
assertTrue(userService.delete(1581111));
}
```
需要注意初始化的顺序,`@Mock`的顺序优先于`@MockPrimary`,即先使用Mockito初始化Mock对象,再使用TestPie指定该对象的Mock类。
### 方式二、使用Junit5的扩展类`PieMockitoExtension`
`PieMockitoExtension`会在每个测试方法执行前初始化拥有注解`@Mock`和`@MockPrimay`对象。
```java
@ExtendWith({ MockitoExtension.class, PieMockitoExtension.class })
public class PieMockitoExtensionTest {
@Mock(lenient = true)
@MockPrimary(UserServiceMock.class)
private UserService userService;
@Test
public void testPrimary() {
assertFalse(userService.delete(1590000));
assertTrue(userService.delete(1581111));
}
}
```
## `@MockProvider`:为某个测试方法提供mock
`@MockPrimary`提供了快速Mock一个对象的功能,`@MockProvider`则针对每个测试方法准备Mock功能的方法。`@MockPrimary`是一个对象的Mock,`@MockProvider`则每个测试方法需要所有Mock对象的Mock,它是测试方法级别的。
1). 创建测试类的TestClassMock类:
```java
public class MockProviderTestClassMock {
@PieData("/pie/list_user_.json")
private List userList;
private UserService userService;
public MockProviderTestClassMock() {
Pie.initAnnotations(this);
}
public void mock_testProvider() {
given(userService.find(anyLong())).willReturn(userList.get(1));
}
}
```
2). 使用`@MockProvider`指定TestClassMock:
```java
@ExtendWith({ MockitoExtension.class, PieMockitoExtension.class })
@MockProvider(MockProviderTestClassMock.class)
public class MockProviderTest {
@Mock(lenient = true)
@MockPrimary(UserServiceMock.class)
private UserService userService;
@Test
public void testPrimary() {
// use primary mock
User findUser = userService.find(12306);
Assertions.assertEquals(findUser.getName(), "Sayi");
}
@Test
public void testProvider() {
// user provider mock
User findUser = userService.find(12306);
Assertions.assertEquals(findUser.getName(), "Van");
}
}
```
每个测试方法会自动寻找`@MockProvider`指定类的前缀为mock_的同名方法去初始化Mock功能,比如testProvider方法执行前会执行MockProviderTestClassMock的mock_testProvider方法。
`@MockProvider`的Mock功能会覆盖`@MockPrimary`的功能,即优先级更高。
## 愿景
希望TestPie未来能带来更好的単测编码体验。