ibr*_*maz 875 java unit-testing mocking void mockito
如何用void返回类型模拟方法?
我实现了一个观察者模式,但我无法用Mockito模拟它,因为我不知道如何.
我试图在互联网上找到一个例子,但没有成功.
我的班级看起来像
public class World {
List<Listener> listeners;
void addListener(Listener item) {
listeners.add(item);
}
void doAction(Action goal,Object obj) {
setState("i received");
goal.doAction(obj);
setState("i finished");
}
private string state;
//setter getter state
}
public class WorldTest implements Listener {
@Test public void word{
World w= mock(World.class);
w.addListener(this);
...
...
}
}
interface Listener {
void doAction();
}
Run Code Online (Sandbox Code Playgroud)
系统不会通过模拟触发.=(我想显示上面提到的系统状态.并根据它们做出断言.
sat*_*esh 1076
看看Mockito API文档.由于链接的文档提到(点#12),你可以使用任何的doThrow(),doAnswer(),doNothing(),doReturn()家人从框架的Mockito的方法来嘲笑无效的方法.
例如,
Mockito.doThrow(new Exception()).when(instance).methodName();
Run Code Online (Sandbox Code Playgroud)
或者如果你想将它与后续行为相结合,
Mockito.doThrow(new Exception()).doNothing().when(instance).methodName();
Run Code Online (Sandbox Code Playgroud)
假设你正在嘲笑setState(String s)下面的类World中的setter 是代码使用doAnswer方法来模拟setState.
World mockWorld = mock(World.class);
doAnswer(new Answer<Void>() {
public Void answer(InvocationOnMock invocation) {
Object[] args = invocation.getArguments();
System.out.println("called with arguments: " + Arrays.toString(args));
return null;
}
}).when(mockWorld).setState(anyString());
Run Code Online (Sandbox Code Playgroud)
小智 102
我想我已经找到了一个更简单的问题答案,只为一个方法调用真正的方法(即使它有一个void返回)你可以这样做:
Mockito.doCallRealMethod().when(<objectInstance>).<method>();
<objectInstance>.<method>();
Run Code Online (Sandbox Code Playgroud)
或者,您可以为该类的所有方法调用实际方法,执行以下操作:
<Object> <objectInstance> = mock(<Object>.class, Mockito.CALLS_REAL_METHODS);
Run Code Online (Sandbox Code Playgroud)
Omr*_*374 66
添加到@sateesh所说的,当你只想模拟一个void方法以防止测试调用它时,你可以这样使用Spy:
World world = new World();
World spy = Mockito.spy(world);
Mockito.doNothing().when(spy).methodToMock();
Run Code Online (Sandbox Code Playgroud)
如果要运行测试,请确保在spy对象上调用方法而不是world对象.例如:
assertEquals(0,spy.methodToTestThatShouldReturnZero());
Run Code Online (Sandbox Code Playgroud)
ibr*_*maz 58
所谓问题的解决方案是使用spy Mockito.spy(...)而不是mock Mockito.mock(..).
间谍使我们能够进行部分嘲弄.Mockito擅长此事.因为你的课程不完整,所以你可以通过这种方式在这个课堂上模拟一些必修课.
fl0*_*l0w 31
首先:你应该总是导入mockito static,这样代码将更具可读性(和直观性):
import static org.mockito.Mockito.*;
Run Code Online (Sandbox Code Playgroud)
对于部分嘲笑并仍然保持其余的mockito提供"Spy"的原始功能.
您可以按如下方式使用它:
private World world = spy(World.class);
Run Code Online (Sandbox Code Playgroud)
要消除执行方法,您可以使用以下内容:
doNothing().when(someObject).someMethod(anyObject());
Run Code Online (Sandbox Code Playgroud)
为方法提供一些自定义行为使用"when"与"thenReturn":
doReturn("something").when(this.world).someMethod(anyObject());
Run Code Online (Sandbox Code Playgroud)
有关更多示例,请在doc中找到mockito示例.
Dil*_*sha 24
如何使用mockito模拟void方法 - 有两种选择:
doAnswer - 如果我们希望我们的模拟void方法做某事(尽管是无效的模拟行为).doThrow- Mockito.doThrow()如果你想从模拟的void方法中抛出一个异常,那就有了.以下是如何使用它的示例(不是理想的用例,只是想说明基本用法).
@Test
public void testUpdate() {
doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
Object[] arguments = invocation.getArguments();
if (arguments != null && arguments.length > 1 && arguments[0] != null && arguments[1] != null) {
Customer customer = (Customer) arguments[0];
String email = (String) arguments[1];
customer.setEmail(email);
}
return null;
}
}).when(daoMock).updateEmail(any(Customer.class), any(String.class));
// calling the method under test
Customer customer = service.changeEmail("old@test.com", "new@test.com");
//some asserts
assertThat(customer, is(notNullValue()));
assertThat(customer.getEmail(), is(equalTo("new@test.com")));
}
@Test(expected = RuntimeException.class)
public void testUpdate_throwsException() {
doThrow(RuntimeException.class).when(daoMock).updateEmail(any(Customer.class), any(String.class));
// calling the method under test
Customer customer = service.changeEmail("old@test.com", "new@test.com");
}
}
Run Code Online (Sandbox Code Playgroud)
您可以在我的帖子中找到有关如何使用Mockito 模拟和测试 void方法的更多详细信息如何使用Mockito 进行模拟(带示例的综合指南)
jav*_*y79 16
添加另一个答案(没有双关语)......
如果你不能\不想使用间谍,你需要调用doAnswer方法.但是,您不一定需要推出自己的答案.有几个默认实现.值得注意的是,CallsRealMethods.
在实践中,它看起来像这样:
doAnswer(new CallsRealMethods()).when(mock)
.voidMethod(any(SomeParamClass.class));
Run Code Online (Sandbox Code Playgroud)
要么:
doAnswer(Answers.CALLS_REAL_METHODS.get()).when(mock)
.voidMethod(any(SomeParamClass.class));
Run Code Online (Sandbox Code Playgroud)
Tim*_*m B 15
在Java 8中,假设您具有以下静态导入,则可以使其更加清晰org.mockito.Mockito.doAnswer:
doAnswer(i -> {
// Do stuff with i.getArguments() here
return null;
}).when(*mock*).*method*(*methodArguments*);
Run Code Online (Sandbox Code Playgroud)
这return null;很重要,如果没有它,编译将失败并出现一些相当模糊的错误,因为它无法找到合适的覆盖doAnswer.
例如ExecutorService,只需立即执行任何Runnable传递,execute()就可以使用以下方法实现:
doAnswer(i -> {
((Runnable) i.getArguments()[0]).run();
return null;
}).when(executor).execute(any());
Run Code Online (Sandbox Code Playgroud)
我认为你的问题是由于你的测试结构.我发现很难将mocking与在测试类中实现接口的传统方法混合在一起(正如你在这里所做的那样).
如果您将侦听器实现为Mock,则可以验证交互.
Listener listener = mock(Listener.class);
w.addListener(listener);
world.doAction(..);
verify(listener).doAction();
Run Code Online (Sandbox Code Playgroud)
这应该让你满意的是'世界'正在做正确的事情.
| 归档时间: |
|
| 查看次数: |
725928 次 |
| 最近记录: |