Mockito打桩测试包括以下几个步骤:
- 创建Mock对象:使用Mockito的mock()方法创建一个模拟对象,该对象将模拟我们要测试的方法或类所依赖的外部对象。
- Stub方法调用:使用when()和thenReturn()等方法定义Mock对象在被调用时应如何响应。这可以让我们控制Mock对象的行为,以便在测试中模拟不同的场景。
- 验证方法调用:使用verify()方法验证Mock对象的方法是否被正确调用。这可以帮助我们确保测试代码按照预期执行,并发现任何潜在的问题。
以下demo简单演示: 使用Mockito框架来模拟(mock)和测试桩(stub)对象的行为,以便在编写单元测试代码时测试某个方法或类的功能
ps: 以下demo未使用verify()流程
方式一: 判断参数,根据不同参数判断,返回不同结果
import lombok.Data;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentMatchers;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when;
class ProcessorTest {
@Data
class Flower{
private String name;
private int age;
public Flower(String name,int age) {
this.age = age;
this.name = name;
}
}
class FlowerService{
public String isABigFlower(String name,int age){
return "response";
}
}
@Test
void testArgumentMatchers(){
MockitoAnnotations.initMocks(this);
FlowerService flowerService = Mockito.mock(FlowerService.class);
// when(flowerService.isABigFlower(ArgumentMatchers.eq("poppy"), ArgumentMatchers.anyInt())).thenReturn("response1");
when(flowerService.isABigFlower(ArgumentMatchers.eq("poppy1"), ArgumentMatchers.anyInt())).thenReturn("response1");
when(flowerService.isABigFlower(ArgumentMatchers.eq("poppy2"), ArgumentMatchers.anyInt())).thenReturn("response2");
// Flower flower = new Flower("poppy", 15);
String response = flowerService.isABigFlower("poppy1", 15);
System.out.println("poppy1" + response);
response = flowerService.isABigFlower("poppy2", 15);
System.out.println("poppy2" + response);
response = flowerService.isABigFlower("poppy", 15);
System.out.println("poppy2" + response);
}
}
方式二: 在以上的基础上再增加根据调用次数,返回不同的结果
@Test
void testMasterSlaveModel() {
MockitoAnnotations.initMocks(this);
Request request = Mockito.mock(Request.class);
when(request.post(anyString(),any(),any(),any(),any()))
.thenAnswer(invocation -> {
// 同一个方法,被多次调用时,获取调用次数
int callCount = Mockito.mockingDetails(request).getInvocations().size();
if (callCount == 1) {
return new Result<>(500,"请先添加司机");
} else if (callCount == 2) {
return new Result<>(500,"请先添加车辆");
} else {
return new Result<>(0,"操作成功");
}
});
// 构造上下文context
// 调用业务方法(业务方法内使用了Request::post方法)
// 验证结果...
}
方式三: 在以上的基础上,再增加根据参数的不同区分调用次数,返回不同的结果
@Test
void testMasterSlaveModel() {
MockitoAnnotations.initMocks(this);
Request request = Mockito.mock(Request.class);
AtomicInteger callOrderTime = new AtomicInteger();
when(request.post(anyString(),any(),any(),any(),any()))
.thenAnswer(invocation -> {
if (invocation.getArgument(0) == "order") {
callOrderTime.getAndIncrement();
if (callOrderTime.get() == 1) {
return new Result<>(500,"请先添加司机");
}else if( callOrderTime.get() == 2){
return new Result<>(500,"请先添加车辆");
}else {
return new Result<>(0,"操作成功");
}
} else if (invocation.getArgument(0) == "driver") {
if (callOrderTime.get() == 1) {
return new Result<>(500,"司机姓名为空");
}
return new Result<>(0,"操作成功");
} else if (invocation.getArgument(0) == "car") {
return new Result<>(0,"操作成功");
}
return null;
});
// 构造上下文context
// 调用业务方法(业务方法内使用了Request::post方法)
// 验证结果...
}