Mockito似乎是一个非常甜蜜的Java存根/模拟框架.唯一的问题是我找不到关于使用API的最佳方法的任何具体文档.测试中使用的常用方法包括:
doXXX(???) : Stubber
when(T) : OngoingStubbing
then(T) : OngoingStubbing
verify(???) : T
given(T) : BDDOngoingStubbing
willXXX(???) : BDDStubber
Run Code Online (Sandbox Code Playgroud)
当你在实践中看到Mockito的例子时,你会看到如下代码:
when(yourMethod()).thenReturn(5);
Run Code Online (Sandbox Code Playgroud)
从我读过的所有文档中,我已经确定了Mockito"语法"的几个"模式",它们是通过菊花链式连接这些方法调用获得的,就像上面的例子一样.我发现的一些常见模式是:
当/ Then: when(yourMethod()).thenReturn(5);
给定/将:给定(yourMethod()).willThrow(OutOfMemoryException.class);
Do/When: doReturn(7).when(yourMock.fizzBuzz());
Will/Given/Do: willReturn(any()).given(yourMethod()).doNothing();
验证/执行:验证(yourMethod()).doThrow(SomeException.class);
我正在窒息的是如何选择正确的模式/方法调用组合来模拟我的测试用例.看起来你可以在看似无穷无尽的组合中将它们连接在一起,我不确定哪种模式适合哪个问题.
一些Mockito Guru可以帮助阐明Mockito方法的哪些模式/组合用于哪种类型的测试用例(以及为什么)?提前致谢!
我正在用mockito验证一个方法已被调用.方法:
public void createButtons(final List<Button> buttonsConfiguration) {...}
Run Code Online (Sandbox Code Playgroud)
由于传递哪个列表无关紧要,因此我验证该方法的调用方式如下:
verify(mock).createButtons(Matchers.anyListOf(Button.class));
Run Code Online (Sandbox Code Playgroud)
但是,它的大小List很重要.因此,List列表必须具有X元素并不重要.
这有可能吗?
我在我的类中使用私有静态最终LOGGER字段,我希望LOGGER.isInfoEnabled()方法返回false.如何使用mockito或jMockit模拟静态final字段
我的班级是:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Class1 {
private static final Logger LOGGER = LoggerFactory.getLogger(Class1.class);
public boolean demoMethod() {
System.out.println("Demo started");
if (LOGGER.isInfoEnabled()) {
System.out.println("@@@@@@@@@@@@@@ ------- info is enabled");
} else {
System.out.println("info is disabled");
}
return LOGGER.isInfoEnabled();
}
}
Run Code Online (Sandbox Code Playgroud)
它的junit是:
import mockit.Mocked;
import mockit.NonStrictExpectations;
import org.mockito.InjectMocks;
import org.mockito.MockitoAnnotations;
import org.slf4j.Logger;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
import com.source.Class1;
public class MyTest {
@InjectMocks
Class1 cls1;
@BeforeMethod
public void initMocks() { …Run Code Online (Sandbox Code Playgroud) 我需要模拟一个测试场景,我在其中调用getBytes()String对象的方法,并得到UnsupportedEncodingException.
我试图使用以下代码实现:
String nonEncodedString = mock(String.class);
when(nonEncodedString.getBytes(anyString())).thenThrow(new UnsupportedEncodingException("Parsing error."));
Run Code Online (Sandbox Code Playgroud)
问题是,当我运行我的测试用例时,我得到一个MockitoException,表示我无法模拟java.lang.String类.
有没有办法使用mockito模拟String对象,或者,当我调用getBytes方法时,一种方法使我的String对象抛出UnsupportedEncodingException?
以下是更多细节来说明问题:
这是我要测试的类:
public final class A {
public static String f(String str){
try {
return new String(str.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
// This is the catch block that I want to exercise.
...
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的测试类(我使用的是JUnit 4和mockito):
public class TestA {
@Test(expected=UnsupportedEncodingException.class)
public void test(){
String aString = mock(String.class);
when(nonEncodedString.getBytes(anyString())).thenThrow(new UnsupportedEncodingException("Parsing error."));
A.f(aString);
}
}
Run Code Online (Sandbox Code Playgroud) 我有一个可以多次调用的模拟对象的方法(想想递归).该方法定义如下:
public void doCommit() { }
Run Code Online (Sandbox Code Playgroud)
为了告诉它失败,我使用这个约定:
doThrow(new RuntimeException()).when(mMockedObject).doCommit();
Run Code Online (Sandbox Code Playgroud)
但是,这会使该方法在调用它时抛出此异常.我怎样才能这样做,例如,它只在第一次和第三次被调用时抛出它?这意味着,例如,第二次和第四次它只返回而不抛出异常.请注意,我不是doCommit()的作者,也没有可以更改的源代码.
我正在使用slf4j,我想对我的代码进行单元测试,以确保在某些条件下生成警告/错误日志消息.我宁愿这些是严格的单元测试,所以我不想从文件中提取日志配置以测试日志消息的生成.我正在使用的模拟框架是Mockito.
如何模拟集成测试所需的许多依赖项?
我使用Mockito进行"纯粹的"单元测试.在这种情况下,'Pure'意味着测试单个类,模拟它的所有依赖项.美丽.
现在进行集成测试.让我们说在这种情况下,集成测试将测试这样的事情:
我们还要说步骤2中发生的处理是严肃的事情.它依赖于大量的数据库交互,多个外部服务,文件系统,各种各样的东西.流会触发很多副作用,所以我不能简单地确保响应是正确的 - 我需要验证副作用.
这些依赖项中的每一个都由一个无状态服务类包装,这使得它们很好并且可以模拟.
人们如何处理这个?
我很想使用Mockito,这样我就可以验证上述流程会产生的副作用.然而,Mocktio的文档(在很大程度上它的实现)似乎强烈反对在"纯"单元测试之外的上下文中使用它.我试过这条路,但是
编辑
我知道我可以像HSQLDB实例那样处理数据库问题,但仍然存在外部服务的问题.为了重复性,我不能依赖那些服务,处于我需要的状态,等等.我看到的唯一选择是嘲笑它们.
Whatdaya呢?
我有一节课.
Class First {
private Second second;
public First(int num, String str) {
second = new Second(str);
this.num = num;
}
... // some other methods
}
Run Code Online (Sandbox Code Playgroud)
我想为First类的公共方法编写单元测试.我想避免执行类Second的构造函数.
我这样做了:
Second second = Mockito.mock(Second.class);
Mockito.when(new Second(any(String.class))).thenReturn(null);
First first = new First(null, null);
Run Code Online (Sandbox Code Playgroud)
它仍在调用类Second的构造函数.我怎么能避免呢?
我有一个使用一些Spring上下文的测试.在这些上下文中,声明了许多bean.我希望测试使用上下文的bean的实际实现,除了其中一个,我想要使用MOCK.
我尝试将Test作为一个配置组件(使用@Configuration注释),但XML似乎优先于@Bean注释,因此它不起作用,这样:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"context1.xml", "context2.xml", ...})
@Configuration
public class MyTest{
@Inject
private MyTargetBean target;
private AnotherBean myMock = mock(AnotherBean.class);
@Bean
public AnotherBean myMock() { return myMock; }
.....
Run Code Online (Sandbox Code Playgroud)
我知道我可以在XML中定义Mocks,但为此我需要为每个测试添加一个额外的XML文件,我希望在其中执行此操作.我想避免这种复杂性.
有没有办法在一个上下文中注入bean(比如模拟)而不是通过XML?
谢谢!
我有这样的方法声明
private Long doThings(MyEnum enum, Long otherParam);
这个枚举
public enum MyEnum{
VAL_A,
VAL_B,
VAL_C
}
Run Code Online (Sandbox Code Playgroud)
问题:如何模拟doThings()通话?我无法匹敌MyEnum.
以下不起作用:
Mockito.when(object.doThings(Matchers.any(), Matchers.anyLong()))
.thenReturn(123L);
Run Code Online (Sandbox Code Playgroud)