我正在使用Mockito 1.9.0.我想在JUnit测试中模拟一个类的单个方法的行为,所以我有
final MyClass myClassSpy = Mockito.spy(myInstance);
Mockito.when(myClassSpy.method1()).thenReturn(myResults);
Run Code Online (Sandbox Code Playgroud)
问题是,在第二行,myClassSpy.method1()实际上是被调用,导致异常.我使用模拟的唯一原因是,以后,无论什么时候myClassSpy.method1()被调用,都不会调用真正的方法并myResults返回对象.
MyClass是一个接口myInstance,如果重要的话就是它的实现.
我需要做些什么来纠正这种间谍行为?
我在这里读了几个关于静态方法的线程,我想我明白了误用/过度使用静态方法会导致的问题.但我并没有真正了解为什么很难模拟静态方法.
我知道其他嘲笑框架,如PowerMock,可以做到这一点,但为什么不能Mockito?
我读过这篇文章,但作者似乎在虔诚地反对这个词static,也许这是我理解不足的原因.
一个简单的解释/链接将是伟大的.
这里Utils.java是我要测试的类,以下是在UtilsTest类中调用的方法.即使我正在嘲笑Log.e方法,如下所示
@Before
public void setUp() {
when(Log.e(any(String.class),any(String.class))).thenReturn(any(Integer.class));
utils = spy(new Utils());
}
Run Code Online (Sandbox Code Playgroud)
我收到以下异常
java.lang.RuntimeException: Method e in android.util.Log not mocked. See http://g.co/androidstudio/not-mocked for details.
at android.util.Log.e(Log.java)
at com.xxx.demo.utils.UtilsTest.setUp(UtilsTest.java:41)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Run Code Online (Sandbox Code Playgroud) 我有一个非常简单的测试用例,它使用的是Mockito和Spring Test框架.当我做
when(pcUserService.read("1")).thenReturn(pcUser);
Run Code Online (Sandbox Code Playgroud)
我得到了这个例外.
org.mockito.exceptions.misusing.MissingMethodInvocationException:
when() requires an argument which has to be 'a method call on a mock'.
For example:
when(mock.getArticles()).thenReturn(articles);
Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
Those methods *cannot* be stubbed/verified.
2. inside when() you don't call method on mock but on some other object.
at com.project.cleaner.controller.test.PcUserControllerTest.shouldGetPcUser(PcUserControllerTest.java:93)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
Run Code Online (Sandbox Code Playgroud)
我尝试过不同的方法,但继续收到此错误消息.我正在使用Spring 3.1.0.RELEASE和Mockito.请分享并指导我正确的方向.
我需要测试一些遗留代码,它在方法调用中使用单例.测试的目的是确保clas sunder测试调用单例方法.我在SO上看到过类似的问题,但是所有的答案都需要其他依赖项(不同的测试框架) - 我很遗憾只能使用Mockito和JUnit,但这种流行的框架应该是完全可能的.
单身人士:
public class FormatterService {
private static FormatterService INSTANCE;
private FormatterService() {
}
public static FormatterService getInstance() {
if (INSTANCE == null) {
INSTANCE = new FormatterService();
}
return INSTANCE;
}
public String formatTachoIcon() {
return "URL";
}
}
Run Code Online (Sandbox Code Playgroud)
被测试的课程:
public class DriverSnapshotHandler {
public String getImageURL() {
return FormatterService.getInstance().formatTachoIcon();
}
}
Run Code Online (Sandbox Code Playgroud)
单元测试:
public class TestDriverSnapshotHandler {
private FormatterService formatter;
@Before
public void setUp() {
formatter = mock(FormatterService.class);
when(FormatterService.getInstance()).thenReturn(formatter);
when(formatter.formatTachoIcon()).thenReturn("MockedURL");
}
@Test
public void testFormatterServiceIsCalled() { …Run Code Online (Sandbox Code Playgroud) 有一种方法有可变参数:
class A {
public void setNames(String... names) {}
}
Run Code Online (Sandbox Code Playgroud)
现在我想用它来模拟它mockito,并捕获传递给它的名字.但我找不到一种方法来捕获任意数量的名字,我只能这样得到它们:
ArgumentCaptor<String> captor1 = ArgumentCaptor.fromClass(String.class);
ArgumentCaptor<String> captor2 = ArgumentCaptor.fromClass(String.class);
A mock = Mockito.mock(A.class);
mock.setNames("Jeff", "Mike");
Mockito.verity(mock).setNames(captor1.capture(), captor2.capture());
String name1 = captor1.getValue(); // Jeff
String name2 = captor2.getValue(); // Mike
Run Code Online (Sandbox Code Playgroud)
如果我传递三个名字,它就无法工作,我必须定义一个captor3来捕获第三个名字.
怎么解决?
我使用 Mockito 和mockito-inline来模拟静态方法。我正在尝试将doNothing类似的行为应用于静态 void 方法。以下解决方法有效,但我认为应该有一种更方便的方法来用更少的代码实现此目的。
try (MockedStatic<UtilCalss> mock = Mockito.mockStatic(UtilCalss.class)) {
mock.when(() -> UtilCalss.staticMethod(any()))
.thenAnswer((Answer<Void>) invocation -> null);
}
Run Code Online (Sandbox Code Playgroud)
如果它是一个非静态方法,我们可以简单地这样做:
doNothing().when(mock).nonStaticMethod(any());
Run Code Online (Sandbox Code Playgroud)
但我想对静态方法做同样的事情。
以下行似乎模拟了类中的所有静态方法:
MockedStatic <Sample> sampleMock = Mockito.mockStatic( Sample.class );
sampleMock.when( () -> Sample.sampleStaticMethod( Mockito.any( String.class ) ) ).thenReturn( "response" );
Run Code Online (Sandbox Code Playgroud)
是否可以只模拟一个类中的一个静态方法?
我有一个类,它连接到H2数据库并运行几个SQL语句.
public class H2Persistence implements IPersistence {
private Connection conn;
@Override
public void open() {
try
{
Class.forName("org.h2.Driver");
conn = DriverManager.getConnection(CONN_TYPE_USER_HOME);
final Statement stmt = conn.createStatement();
stmt.executeUpdate("CREATE TABLE PERSON(" +
"ID BIGINT,"+
"AGEGROUP VARCHAR(255),"+
"MONTHLY_INCOME_LEVEL VARCHAR(255)," +
"GENDER VARCHAR(1),"+
"HOUSEHOLD_ID BIGINT)");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
...
}
Run Code Online (Sandbox Code Playgroud)
我想编写一个单元测试,它验证在open方法中执行某个SQL语句(DROP TABLE IF EXISTS PERSON).
为了做到这一点,我写了以下测试:
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.powermock.api.mockito.PowerMockito.mockStatic;
import static org.powermock.api.mockito.PowerMockito.when;
@RunWith(PowerMockRunner.class) …Run Code Online (Sandbox Code Playgroud) 我有以下代码从DB获取当前计数器值.然后它更新DB中的计数器,然后再次检索该值.
int current = DBUtil.getCurrentCount();
DBUtil.updateCount(50);// it updates the current count by adding 50
int latest = DBUtil.getCurrentCount();
Run Code Online (Sandbox Code Playgroud)
我想以这样的方式模拟静态方法,即第一个调用应返回100,第二个调用应返回150.如何使用PowerMockito实现此目的?我正在使用TestNG,Mockito和PowerMock.
mockito ×10
java ×8
mocking ×4
junit ×3
unit-testing ×3
android ×1
controller ×1
junit5 ×1
methods ×1
powermock ×1
powermockito ×1
spring-test ×1
static ×1