我如何模拟实施类



我有类似的东西:

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返回一些预定义的响应。但是以某种方式,真正的someMethod被调用,而不是返回预定义的响应。我如何使它起作用?

这是我尝试使用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);
      }
}

这是一个没有框架的依赖项的示例:

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);
  }
}

您不必这样做。

您将正在测试的方法更改为不直接调用新调用。

相反,您使用依赖注入。

是的,这可以用PowerMock来完成,但是请相信我:这样做是错误的方法!

此答案与安德烈亚斯(Andreas)发布的答案非常相似,唯一的区别是,您可以使用@runwith(SpringRunner.Class)运行此答案,并且可以避免bean实例化和额外配置的问题。避免使用PowerMocks并仅在需要模拟静态类时才使用。

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);
  }
}

相关内容

  • 没有找到相关文章

最新更新