使用 Mockito 的 When 方法时出现问题

发布于 2024-12-07 07:02:25 字数 2146 浏览 0 评论 0原文

我正在努力自学 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 为零(见上文),< em>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(),而只是返回 true > 相反,每当我测试类时调用它(“systemUnderTest”)。谁能帮助我克服这一点(或者让我的大脑有一些感觉)?

我正在链接 mockito-all-1.8.5.jar 和 JUnit 4。

非常感谢所有阅读本文的人。

拉斯

I'm struggling trying to teach myself Mockito.

Consider the following method, hasInventory(), which should not really run in my way of thinking, but get set up to return true or false as I squirrel-cage my test. Class Warehouse is my "mocked-dependency".

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 );
  }
  ...

In the JUnit test code, the first when() throws an exception because it literally interprets the method call (executing it) and, inventory being nil (see above), InventoryDoesNotExistException is thrown. There are other methods in the mocked-dependency class too, like add() and 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 );

As I understand it, by the when() method, I'm asking Mockito precisely not to call hasInventory(), but just to return true instead whenever it's called as I test the class ("systemUnderTest"). Can anyone help me get past this point (or get some sense into my brain)?

I'm linking mockito-all-1.8.5.jar and JUnit 4.

Copious thanks to all who read this.

Russ

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

念三年u 2024-12-14 07:02:25

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

一般来说,最好是模拟接口,但这不是强制性的。

Mockito FAQfinal 类或方法>,这是由于用于创建模拟的运行时类生成技术所致。

Mockito cannot mock final classes or methods. Try removing the final modifier from the hasInventory method. Or better yet, do not mock the Warehouse class, instead mock the IWarehouse interface, whose methods cannot be final, and presumably defines those used by Order.

In general, it's preferable to mock interfaces, but it's not mandatory.

Not being able to mock final classes or methods is briefly mentioned in the Mockito FAQ, it is due to the runtime class generation technique used for creating the mocks.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文