当前位置: 首页 > 知识库问答 >
问题:

如何模拟实现类?

西门智
2023-03-14

我有这样的东西:

public interface SomeInterface {
    public String someMethod(String someArg1, String someArg2);
}

public class SomeInterfaceImpl {

    @Override
    public String someMethod(String someArg1, String someArg2) {
        String response;

        // a REST API call which fetches response (need to mock this)

        return response;
    }
}

public class SomeClass {

    public int execute() {

        int returnValue;

        // some code

        SomeInterface someInterface = new SomeInterfaceImpl();
        String response = someInterface.someMethod("some1", "some2");

        // some code

        return returnValue;
    }
}

我想使用JUnit测试SomeClass中的execute()方法。由于someMethod(String someArg1,String someArg2)调用了REST API,所以我想模拟someMethod来返回一些预定义的响应。但不知何故,实际的somethod被调用,而不是返回预定义的响应。我如何让它工作?

以下是我尝试使用Mockito和PowerMockito的内容:

@RunWith(PowerMockRunner.class)
@PrepareForTest({ SomeInterface.class, SomeInterfaceImpl.class, SomeClass.class })
public class SomeClassTest {

    @Test
    public void testExecute() {
        String predefinedResponse = "Some predefined response";
        int expectedReturnValue = 10;

        SomeInterfaceImpl impl = PowerMockito.mock(SomeInterfaceImpl.class);
        PowerMockito.whenNew(SomeInterfaceImpl.class).withAnyArguments().thenReturn(impl);
        PowerMockito.when(impl.someMethod(Mockito.any(), Mockito.any())).thenReturn(predefinedResponse);

        SomeClass someClass = new SomeClass();
        int actualReturnValue = someClass.execute();
        assertEquals(expectedReturnValue, actualReturnValue);
      }
}

共有3个答案

轩辕华辉
2023-03-14

这个答案与Andreas发布的答案非常相似,唯一的区别是您可以使用@RunWith(SpringRunner.class)运行它,它将避免bean实例化和额外配置的问题。避免PowerMock,仅在需要模拟静态类时使用它。

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;

import org.springframework.test.context.junit4.SpringRunner;

import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.when;

interface SomeInterface {
  String someMethod(String someArg1, String someArg2);
}

class SomeInterfaceImpl implements SomeInterface {

  @Override
  public String someMethod(String someArg1, String someArg2) {
    String response;

    response = "the answer.";// a REST API call which fetches response (need to mock this)

    return response;
  }
}

class SomeClass {
  private final SomeInterface someInterface;

  SomeClass(final SomeInterface someInterface) {
    this.someInterface = someInterface;
  }

  public SomeClass() {
    this(new SomeInterfaceImpl());
  }

  public int execute() {

    int returnValue;

    // some code

    String response = someInterface.someMethod("some1", "some2");

    returnValue = 42; // some code

    return returnValue;
  }
}

@RunWith(MockitoJUnitRunner.class)
class SomeClassTest {
  private static final String SOME_PREDEFINED_RESPONSE = "Some predefined response";
  @Mock
  private SomeInterface someInterface;
  @InjectMocks
  private SomeClass underTest;

  @Before
  public void setup() {
    when(someInterface.someMethod(anyString(), anyString())).thenReturn(SOME_PREDEFINED_RESPONSE);
  }

  @Test
  public void testExecute() {
    int expectedReturnValue = 42;
    int actualReturnValue = underTest.execute();
    assertEquals(expectedReturnValue, actualReturnValue);
  }
}
梁丘宏硕
2023-03-14

你不必那么做。

您将测试中的方法更改为不直接调用new。

相反,您可以使用例如依赖注入。

是的,这可以通过Powermock实现,但请相信我:这样做是错误的方法!

胡禄
2023-03-14

这是一个在没有框架的情况下注入依赖项的示例:

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.when;

interface SomeInterface {
  String someMethod(String someArg1, String someArg2);
}

class SomeInterfaceImpl implements SomeInterface {

  @Override
  public String someMethod(String someArg1, String someArg2) {
    String response;

    response = "the answer.";// a REST API call which fetches response (need to mock this)

    return response;
  }
}

class SomeClass {
  private final SomeInterface someInterface;

  SomeClass(final SomeInterface someInterface) {
    this.someInterface = someInterface;
  }

  public SomeClass() {
    this(new SomeInterfaceImpl());
  }

  public int execute() {

    int returnValue;

    // some code

    String response = someInterface.someMethod("some1", "some2");

    returnValue = 42; // some code

    return returnValue;
  }
}

@RunWith(MockitoJUnitRunner.class)
class SomeClassTest {
  private static final String SOME_PREDEFINED_RESPONSE = "Some predefined response";
  @Mock
  private SomeInterface someInterface;
  @InjectMocks
  private SomeClass underTest;

  @Before
  public void setup() {
    when(someInterface.someMethod(anyString(), anyString())).thenReturn(SOME_PREDEFINED_RESPONSE);
  }

  @Test
  public void testExecute() {
    int expectedReturnValue = 42;
    int actualReturnValue = underTest.execute();
    assertEquals(expectedReturnValue, actualReturnValue);
  }
}
 类似资料:
  • 本文向大家介绍PHP如何获取Cookie并实现模拟登录,包括了PHP如何获取Cookie并实现模拟登录的使用技巧和注意事项,需要的朋友参考一下 一、定义Cookie存储路径 必须使用绝对路径 $cookie_jar = dirname(__FILE__)."/pic.cookie"; 二、获取Cookie 将cookie存入文件 三、模拟浏览器获取验证码 该服务器验证码有漏洞,可以自己指定 取出c

  • 我知道我需要这样的东西 有人能给我一个这个的示例代码吗?。谢谢

  • 1. 前言 通过几个章节的学习,大家对于 Spring 已经有了初步的认知,我们通过案例练习,或者源码追踪,可以粗略的看到 Spring 框架初始化 bean 对象的过程,那么这个章节,我们模拟 Spring 框架的思路,来写一个类似 Spring 加载对象的案例,加深大家的印象。 2. 案例实现思路 2.1 步骤介绍 思路分析: 我们通过写过的案例可以知道: Spring 框架的容器 是一个接口

  • 本文向大家介绍模拟 localStorage 时如何实现过期时间功能相关面试题,主要包含被问及模拟 localStorage 时如何实现过期时间功能时的应答技巧和注意事项,需要的朋友参考一下 function get(name) { const record = JSON.parse(localStorage.getItem(name)); return record.time - Date.no

  • 我创建了一个bean,如下所示 在一个测试类中,我模拟该类如下: 应用程序在没有错误的情况下启动。但是测试并没有模仿bean CustomerEmailSenderImpl2。bean总是被实例化,并执行真正的代码。即使在测试类中从接口到类名的更改也没有帮助: 需要什么来模拟bean CustomerEmailSenderImpl2?

  • 本文向大家介绍C++中string的模拟实现,包括了C++中string的模拟实现的使用技巧和注意事项,需要的朋友参考一下 c++中的string类可以实现字符串对象的一系列操作,如下图就是从cplusplus上截取的string的一部分功能: 接下来我就简单模拟几个函数实现  首先,我们要给出完整的string类,包括构造函数,析构函数,私有成员char* str  并且在类内声明要实现的函数(