使用 Mockito 的 When 方法时出现问题
我正在努力自学 Mockito。
考虑以下方法,hasInventory(),它不应该真正按照我的思维方式运行,但设置为返回 true 或 false当我把我的测试关在笼子里时。 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Mockito 无法模拟
final
类或方法。尝试从hasInventory
方法中删除final
修饰符。或者更好的是,不要模拟Warehouse
类,而是模拟IWarehouse
接口,其方法不能是final
,并且可能定义了订单
。一般来说,最好是模拟接口,但这不是强制性的。
Mockito FAQfinal 类或方法>,这是由于用于创建模拟的运行时类生成技术所致。
Mockito cannot mock
final
classes or methods. Try removing thefinal
modifier from thehasInventory
method. Or better yet, do not mock theWarehouse
class, instead mock theIWarehouse
interface, whose methods cannot befinal
, and presumably defines those used byOrder
.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.