Issue Using Mockito's When Method
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( TA开发者_开发问答LISKER, 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
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.
精彩评论