spy 和 mock不同,不同点是:
- spy 的参数是对象示例,mock 的参数是 class。
- 被 spy 的对象,调用其方法时默认会走真实方法。mock 对象不会。
下面是一个对比:
import org.junit.Assert;
import org.junit.Test;
import static org.mockito.Mockito.*;
class ExampleService {
int add(int a, int b) {
return a+b;
}
}
public class MockitoDemo {
// 测试 spy
@Test
public void test_spy() {
ExampleService spyExampleService = spy(new ExampleService());
// 默认会走真实方法
Assert.assertEquals(3, spyExampleService.add(1, 2));
// 打桩后,不会走了
when(spyExampleService.add(1, 2)).thenReturn(10);
Assert.assertEquals(10, spyExampleService.add(1, 2));
// 但是参数比匹配的调用,依然走真实方法
Assert.assertEquals(3, spyExampleService.add(2, 1));
}
// 测试 mock
@Test
public void test_mock() {
ExampleService mockExampleService = mock(ExampleService.class);
// 默认返回结果是返回类型int的默认值
Assert.assertEquals(0, mockExampleService.add(1, 2));
}
}
spy 对应注解 @Spy,和 @Mock 是一样用的。
import org.junit.Assert;
import org.junit.Test;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
import static org.mockito.Mockito.*;
class ExampleService {
int add(int a, int b) {
return a+b;
}
}
public class MockitoDemo {
@Spy
private ExampleService spyExampleService;
@Test
public void test_spy() {
MockitoAnnotations.initMocks(this);
Assert.assertEquals(3, spyExampleService.add(1, 2));
when(spyExampleService.add(1, 2)).thenReturn(10);
Assert.assertEquals(10, spyExampleService.add(1, 2));
}
}
对于@Spy
,如果发现修饰的变量是 null,会自动调用类的无参构造函数来初始化。
所以下面两种写法是等价的:
// 写法1
@Spy
private ExampleService spyExampleService;
// 写法2
@Spy
private ExampleService spyExampleService = new ExampleService();
如果没有无参构造函数,必须使用写法2。例子:
import org.junit.Assert;
import org.junit.Test;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
class ExampleService {
private int a;
public ExampleService(int a) {
this.a = a;
}
int add(int b) {
return a+b;
}
}
public class MockitoDemo {
@Spy
private ExampleService spyExampleService = new ExampleService(1);
@Test
public void test_spy() {
MockitoAnnotations.initMocks(this);
Assert.assertEquals(3, spyExampleService.add(2));
}
}