如何模拟测试之外的方法class?
How to mock a method which is outside the test class?
我的代码:
class C:
public class C{
public int methodC(){
return 1000;
}
}
class乙:
public class B{
private static C c;
public static int methodB(){
int b = c.methodC();
return b;
}
}
class答:
public class A {
public int methodA(){
int a = B.methodB();
return a;
}
}
class 测试 A:
class TestA{
@InjectMocks
A a;
@Mock
C c;
public void testMethodA(){
when(c.methodC()).thenReturn(5);
int result = a.methodA();
assertEquals(result, 5);
}
}
即使我模拟 c.methodC()
,methodC
调用 methodB
returns null
.
如何模拟 methodC
调用?
我无法更改源代码,只能在 TestA
class 中进行更改
我也不能使用 PowerMockito
。
@Nikhil 根据您对所提问题的更新,完善了我的答案。
Mockito 无法进行静态模拟,正如您所说不能使用 PowerMock 那么@Jnorman 的回答很好。使用 spring 启动和 mockito 来实现这一点,您必须修改 spring 启动启动器测试依赖项以添加新版本的 Mockito,因为 Mockito 3.4.0 支持静态模拟。
Mockito GitHub Link
https://github.com/mockito/mockito/issues/1013
修改后的 POM
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
<exclusion>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>3.4.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>3.4.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.4.0</version>
<scope>test</scope>
</dependency>
修改代码
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.withSettings;
import java.lang.reflect.Method;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.invocation.Invocation;
import org.mockito.invocation.InvocationFactory;
import org.mockito.invocation.MockHandler;
public class TestA {
@Test
public void testMethodA() {
A a = new A();
mockStatic(B.class);
when(B.methodB()).thenReturn(5);
int result = a.methodA();
assertEquals(result, 5);
}
}
class A {
public int methodA() {
int a = B.methodB();
return a;
}
}
class B {
private static C c;
public static int methodB() {
int b = c.methodC();
return b;
}
}
class C {
public int methodC() {
return 1000;
}
}
这是一种使用您的约束使其工作的方法:
A a = new A();
C c = Mockito.mock(C.class);
@Test
public void testMethodA(){
try {
Field c = B.class.getDeclaredField("c");
c.setAccessible(true);
c.set(null, this.c);
} catch (Exception e) {
e.printStackTrace();
}
Mockito.when(c.methodC()).thenReturn(5);
int result = a.methodA();
assertEquals(result, 5);
}
Mockito [3.4.0] can mock static methods!
依赖性
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>3.4.0</version>
<scope>test</scope>
</dependency>
A测试
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mockStatic;
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
public class ATest {
A a = new A();
MockedStatic<B> b = mockStatic( B.class );
@Test
public void testMethodA() {
b.when( B::methodB ).thenReturn( 5 );
assertEquals( a.methodA(), 5 );
}
}
我的代码:
class C:
public class C{
public int methodC(){
return 1000;
}
}
class乙:
public class B{
private static C c;
public static int methodB(){
int b = c.methodC();
return b;
}
}
class答:
public class A {
public int methodA(){
int a = B.methodB();
return a;
}
}
class 测试 A:
class TestA{
@InjectMocks
A a;
@Mock
C c;
public void testMethodA(){
when(c.methodC()).thenReturn(5);
int result = a.methodA();
assertEquals(result, 5);
}
}
即使我模拟 c.methodC()
,methodC
调用 methodB
returns null
.
如何模拟 methodC
调用?
我无法更改源代码,只能在 TestA
class 中进行更改
我也不能使用 PowerMockito
。
@Nikhil 根据您对所提问题的更新,完善了我的答案。
Mockito 无法进行静态模拟,正如您所说不能使用 PowerMock 那么@Jnorman 的回答很好。使用 spring 启动和 mockito 来实现这一点,您必须修改 spring 启动启动器测试依赖项以添加新版本的 Mockito,因为 Mockito 3.4.0 支持静态模拟。
Mockito GitHub Link
https://github.com/mockito/mockito/issues/1013
修改后的 POM
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
<exclusion>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>3.4.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>3.4.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.4.0</version>
<scope>test</scope>
</dependency>
修改代码
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.withSettings;
import java.lang.reflect.Method;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.invocation.Invocation;
import org.mockito.invocation.InvocationFactory;
import org.mockito.invocation.MockHandler;
public class TestA {
@Test
public void testMethodA() {
A a = new A();
mockStatic(B.class);
when(B.methodB()).thenReturn(5);
int result = a.methodA();
assertEquals(result, 5);
}
}
class A {
public int methodA() {
int a = B.methodB();
return a;
}
}
class B {
private static C c;
public static int methodB() {
int b = c.methodC();
return b;
}
}
class C {
public int methodC() {
return 1000;
}
}
这是一种使用您的约束使其工作的方法:
A a = new A();
C c = Mockito.mock(C.class);
@Test
public void testMethodA(){
try {
Field c = B.class.getDeclaredField("c");
c.setAccessible(true);
c.set(null, this.c);
} catch (Exception e) {
e.printStackTrace();
}
Mockito.when(c.methodC()).thenReturn(5);
int result = a.methodA();
assertEquals(result, 5);
}
Mockito [3.4.0] can mock static methods!
依赖性
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>3.4.0</version>
<scope>test</scope>
</dependency>
A测试
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mockStatic;
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
public class ATest {
A a = new A();
MockedStatic<B> b = mockStatic( B.class );
@Test
public void testMethodA() {
b.when( B::methodB ).thenReturn( 5 );
assertEquals( a.methodA(), 5 );
}
}