使用Mockito的When方法出现问题

9

我正在努力学习Mockito。

考虑以下方法hasInventory(),根据我的想法,它不应该真正运行,而是设置为根据我的测试返回truefalse。类Warehouse是我的“模拟依赖项”。

public class Warehouse implements IWarehouse
{
  private Map< String, Integer >    inventory;

  public Warehouse()
  {
    this.inventory = new HashMap< String, Integer >();
  }

  public final boolean hasInventory( String itemname, int quantity )
      throws InventoryDoesNotExistException
  {
    if( inventory == null )
      throw new InventoryDoesNotExistException();

    if( !inventory.containsKey( itemname ) )
      return false;

    int current = ( inventory.containsKey( itemname ) ) ? inventory.get( itemname ) : 0;

    return( current >= quantity );
  }
  ...

在JUnit测试代码中,第一个when()抛出异常,因为它按字面意义解释方法调用(执行它),并且由于inventory为nil(参见上文),所以会抛出InventoryDoesNotExistException。模拟依赖类中还有其他方法,例如add()remove()
@RunWith( MockitoJUnitRunner.class )
public class OrderInteractionTest
{
  private static final String TALISKER = "Talisker";
  private Order   systemUnderTest  = null;

  @Mock
  private Warehouse   mockedDependency = null;

  @Before
  public void init()
  {
    //MockitoAnnotations.initMocks( this );
    //mockedDependency = mock( Warehouse.class );
    this.systemUnderTest  = new Order( TALISKER, 50 );
  }

  @Test  
  public void testFillingRemovesInventoryIfInStock()  
  {  
    try  
    {  
      doNothing().doThrow( new RuntimeException() ).when( mockedDependency ).add( anyString(), anyInt() );  
      doNothing().doThrow( new RuntimeException() ).when( mockedDependency ).remove( anyString(), anyInt() );  
      when( mockedDependency.hasInventory( anyString(), anyInt() ) ).thenReturn( true );  
      when( mockedDependency.getInventory( anyString() ) ).thenReturn( 50 );

据我的理解,通过使用when()方法,我要求Mockito不要调用hasInventory(),而只是在测试这个类(“systemUnderTest”)时返回true。有没有人能帮助我跨越这一点(或让我的大脑感到些许意义)?
我链接了mockito-all-1.8.5.jar和JUnit 4。
感谢所有阅读此内容的人。
Russ
1个回答

10

Mockito无法模拟final类或方法。尝试从hasInventory方法中删除final修饰符。或者更好的方法是不要模拟Warehouse类,而是模拟IWarehouse接口,它的方法不能是final,并且可能定义了Order使用的方法。

通常情况下,最好模拟接口,但不是必须的。

Mockito无法模拟final类或方法,在Mockito FAQ中简要提到,这是由于用于创建模拟对象的运行时类生成技术所致。


哈!是的,这就是问题所在。事实上,我今天早些时候读到了一些关于这个的内容,但我没有联系起来。仿照其他教程,我已经开始模拟IWarehouse并且它也能工作,所以我认为我只能模拟接口(几周前我曾与某人交谈,他告诉我可以模拟简单的类,所以我没有尝试模拟接口,因为我认为在许多实际情况下,我甚至不会有一个接口)。但这才是正确的答案!非常感谢你。 - Russ Bateman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接