我遇到了mockito的问题。
我正在开发一个Web应用程序。在我的测试中,用户管理被嘲笑。
在某些情况下,我必须更改getLoggedInUser()
方法返回的用户。
问题是,我的getLoggedInUser()
方法也可以抛出AuthenticationException
。
因此,当我尝试从无用户切换到某个用户时,调用
when(userProvider.getLoggedInUser()).thenReturn(user);
抛出异常,因为userProvider.getLoggedInUser()
已经与thenTrow()
有没有办法告诉when
方法不关心异常?
提前致谢 - István
答案 0 :(得分:14)
在新的Mockito版本中,您可以使用存根连续调用在第一次调用时抛出异常并在第二次调用时返回值。
when(mock.someMethod("some arg"))
.thenThrow(new RuntimeException())
.thenReturn("foo");
http://docs.mockito.googlecode.com/hg/latest/org/mockito/Mockito.html#stubbing_consecutive_calls
答案 1 :(得分:4)
有没有办法告诉何时方法不关心异常?
要真正回答这个问题:
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.powermock.api.mockito.PowerMockito.mock;
import static org.powermock.api.mockito.PowerMockito.when;
import org.junit.Test;
import org.mockito.Mockito;
import java.util.ArrayList;
public class MyTest {
@Test
public void testA() {
// setup
ArrayList<Object> list = mock(ObjectArrayList.class);
when(list.indexOf(any())).thenReturn(6);
when(list.indexOf(any())).thenReturn(12);
// execute
int index = list.indexOf(new Object());
// verify
assertThat(index, is(equalTo(12)));
}
@Test
public void testB() {
// setup
ArrayList<Object> list = mock(ObjectArrayList.class);
when(list.add(any())).thenThrow(new AssertionError("can't get rid of me!"));
when(list.add(any())).thenReturn(true);
// execute
list.add(new Object());
}
@Test
public void testC() {
// setup
ArrayList<Object> list = mock(ObjectArrayList.class);
when(list.add(any())).thenThrow(new AssertionError("can't get rid of me!"));
Mockito.reset(list);
when(list.add(any())).thenReturn(true);
// execute
list.add(new Object());
}
/**
* Exists to work around the fact that mocking an ArrayList<Object>
* requires a cast, which causes "unchecked" warnings, that can only be suppressed...
*/
class ObjectArrayList extends ArrayList<Object> {
}
}
TestB
由于断言您无法摆脱而失败。 TestC
显示了reset
方法如何用于重置模拟并删除它上的thenThrow
命令。
请注意,重置并不总是在我有一些更复杂的例子中起作用。我怀疑这可能是因为他们使用PowerMockito.mock
而不是Mockito.mock
?
答案 2 :(得分:3)
我对你的问题的第一反应是听起来你试图在一次测试中做太多。
为了便于测试和简化,每个测试应仅测试一件事。这与Single Responsibility Principle相同。我经常发现程序员试图在一次测试中测试多个东西并因此而遇到各种各样的问题。因此,每个单元测试方法都应遵循以下流程:
所以在你的情况下,我希望至少看到两个测试。一个getLoggedInUser()
返回用户,另一个getLoggedInUser()
抛出异常。这样,在模拟中尝试模拟不同的行为就不会有问题。
第二个想到春天的想法不是存根。请考虑使用expect,因为您可以设置一系列期望。即第一个调用返回一个用户,第二个调用抛出异常,第三个调用返回另一个用户,等等。
答案 3 :(得分:2)
听起来你可能不得不使用自定义答案。 Here is an example