标签: mockito

形成Mockito"语法"

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.fizzBu​​zz());

Will/Given/Do: willReturn(any()).given(yourMethod()).doNothing();

验证/执行:验证(yourMethod()).doThrow(SomeException.class);

我正在窒息的是如何选择正确的模式/方法调用组合来模拟我的测试用例.看起来你可以在看似无穷无尽的组合中将它们连接在一起,我不确定哪种模式适合哪个问题.

一些Mockito Guru可以帮助阐明Mockito方法的哪些模式/组合用于哪种类型的测试用例(以及为什么)?提前致谢!

java junit unit-testing mocking mockito

40
推荐指数
3
解决办法
2万
查看次数

mockito给定大小的anyList

我正在用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元素并不重要.

这有可能吗?

java list mockito

40
推荐指数
3
解决办法
3万
查看次数

使用mockito或Jmockit模拟私有静态最终字段

我在我的类中使用私有静态最终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)

java junit jmockit static-members mockito

39
推荐指数
2
解决办法
5万
查看次数

如何使用mockito模拟String?

我需要模拟一个测试场景,我在其中调用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)

java unit-testing mocking mockito

38
推荐指数
5
解决办法
5万
查看次数

如何在第一次调用mocked方法时抛出异常?

我有一个可以多次调用的模拟对象的方法(想想递归).该方法定义如下:

public void doCommit() { }
Run Code Online (Sandbox Code Playgroud)

为了告诉它失败,我使用这个约定:

doThrow(new RuntimeException()).when(mMockedObject).doCommit();
Run Code Online (Sandbox Code Playgroud)

但是,这会使该方法在调用它时抛出此异常.我怎样才能这样做,例如,它只在第一次和第三次被调用时抛出它?这意味着,例如,第二次和第四次它只返回而不抛出异常.请注意,我不是doCommit()的作者,也没有可以更改的源代码.

unit-testing mocking mockito

38
推荐指数
2
解决办法
3万
查看次数

对SLF4J日志消息进行单元测试的最佳方法是什么?

我正在使用slf4j,我想对我的代码进行单元测试,以确保在某些条件下生成警告/错误日志消息.我宁愿这些是严格的单元测试,所以我不想从文件中提取日志配置以测试日志消息的生成.我正在使用的模拟框架是Mockito.

unit-testing mocking slf4j mockito

37
推荐指数
6
解决办法
3万
查看次数

嘲笑集成测试

如何模拟集成测试所需的许多依赖项?

我使用Mockito进行"纯粹的"单元测试.在这种情况下,'Pure'意味着测试单个类,模拟它的所有依赖项.美丽.

现在进行集成测试.让我们说在这种情况下,集成测试将测试这样的事情:

  1. 消息被放入队列中
  2. 消息被"处理"
  3. 响应消息放在响应队列中

我们还要说步骤2中发生的处理是严肃的事情.它依赖于大量的数据库交互,多个外部服务,文件系统,各种各样的东西.流会触发很多副作用,所以我不能简单地确保响应是正确的 - 我需要验证副作用.

这些依赖项中的每一个都由一个无状态服务类包装,这使得它们很好并且可以模拟.

人们如何处理这个?

我很想使用Mockito,这样我就可以验证上述流程会产生的副作用.然而,Mocktio的文档(在很大程度上它的实现)似乎强烈反对在"纯"单元测试之外的上下文中使用它.我试过这条路,但是

  • 填充存根数据很困难(因为它有很多)
  • 让Spring将那些存根实例注入我的bean很困难
  • 很难"重置"模拟,这样我就可以在不清除存根的情况下验证不同的交互集.

编辑

我知道我可以像HSQLDB实例那样处理数据库问题,但仍然存在外部服务的问题.为了重复性,我不能依赖那些服务,处于我需要的状态,等等.我看到的唯一选择是嘲笑它们.

Whatdaya呢?

integration-testing mocking mockito

37
推荐指数
2
解决办法
2万
查看次数

用mockito为构造函数进行单元测试

我有一节课.

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的构造函数.我怎么能避免呢?

java unit-testing mockito

37
推荐指数
5
解决办法
12万
查看次数

如何在Spring上下文中注入模拟

我有一个使用一些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?

谢谢!

java spring dependency-injection mocking mockito

37
推荐指数
2
解决办法
8万
查看次数

Mockito:如何匹配任何枚举参数

我有这样的方法声明

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)

java enums mockito

37
推荐指数
1
解决办法
3万
查看次数