Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

org.mockito.exceptions.misusing.MissingMethodInvocationException:

when() requires an argument which has to be 'a method call on a mock'. For example:

   when(mock.getArticles()).thenReturn(articles);
  

Also, this error might show up because:

  • you stub either of: final/private/equals()/hashCode() methods. Those methods cannot be stubbed/verified.
  • inside when() you don't call method on mock but on some other object.
  • the parent of the mocked class is not public. It is a limitation of the mock engine.
  • Following is my code and the exception was thrown at the second when statement. I don't think that my test code didn't violate what the exception claims. I spent for a while, but couldn't figure out. Could someone help? What I need to test is getPermProducts method. In the getPermProducts method, I want to ignore isTempProduct method. So, when p1 came, I want it returns false, and when p2 came, I want it returns true etc..

    @Named(ProductManager.NAME)
    public class ProductManager {
        @Resource(name = ProductService.NAME)
        private ProductService productService;
        public List<Product> getPermProducts(Set<Product> products) {
            Iterator<Product> it = products.iterator();
            List<Product> cProducts = new ArrayList<Product>();
            Product p;
            while (it.hasNext()) {
                p = it.next();
                if (!isTempProduct(p)) {
                cProducts.add(p);
            return cProducts;
        public Boolean isTempProduct(Product product) {
        if (product instanceof PermProduct) {
        return false;
        Set<ProductItems> pItems = product.getProductItems();
            if (pItems.isEmpty()) {
            return false;
        Iterator<ProductItem> itr = pItems.iterator();
        while (itr.hasNext()) {
            if (itr.next() instanceof TempItem) {
                return true;
        return false;
    public Product getProduct(Integer productId) {
        Product p = productService.getProduct(productId);
        return p;
    @RunWith(MockitoJUnitRunner.class)
    public class ProductManagerTest {
        @InjectMocks
        private ProductManager mockProductManager;
        @Mock
        private ProductService mockProductService;//not being used here
        private static final Integer PRODUCT_ID_1 = 1;
        private static final Integer PRODUCT_ID_2 = 2;
        @Test
        public void getProduct(){
            Product p1 = mock(PermProduct.class);
                p1.setProductId(PRODUCT_ID_1);
            when(mockProductManager.getProductId()).thenReturn(PRODUCT_ID_1);
            when(mockProductManager.isTempProduct(p1)).thenReturn(false);
                Product p2 = mock(TempProduct.class);
                p2.setProductId(PRODUCT_ID_2);
                when(mockProductManager.isTempProduct(p2)).thenReturn(true);
                List<Product> products = Mock(List.class);
                products.add(p1);
                products.add(p2);
                Iterator<Product> pIterator = mock(Iterator.class);
                when(prodcuts.iterator()).thenReturn(pIterator);
                when(pIterator.hasNext()).thenReturn(true, true, false);
        when(pIterator.next()).thenReturn(p1, p2);
                asserEquals(1, mockProductManager.getPermProducts(products).size());
    

    SOLUTION: I updated my test based on enterbios's answer. I used partial mocking, but as enterbios suggested, we should avoid it, but sometimes we need it. I found that we can have both non-mocked and partial mocked class same time.

    @RunWith(MockitoJUnitRunner.class)
    public class ProductManagerTest {
        @InjectMocks
        private ProductManager productManager;//not being used here
        @Mock
        private ProductService mockProductService;//not being used here
        private OtherService other = new OtherService();//not being used here
        @InjectMocks
        final ProductManager partiallyMockedProductManager = spy(new ProductManager());
        private static final Integer PRODUCT_ID_1 = 1;
        private static final Integer PRODUCT_ID_2 = 2;
        @Test
        public void getProduct() {
            Product p1 = new PermProduct();
            p1.setProductId(PRODUCT_ID_1);
            Product p2 = new Product();
            p2.setProductId(PRODUCT_ID_2);
            List<Product> products = new ArrayList<Product>();
            products.add(p1);
            products.add(p2);
            doReturn(false).when(partiallyMockedProductManager).isTempProduct(p1);
            doReturn(true).when(partiallyMockedProductManager).isTempProduct(p2);
            assertEquals(1, partiallyMockedProductManager.getPermProducts(products).size());
            verify(partiallyMockedProductManager).isTempProduct(p1);
            verify(partiallyMockedProductManager).isTempProduct(p2);
    

    Your mockProductManager is actually not a mock but an instance of ProductManager class. You shouldn't mock a tested object. The way to mock some methods from tested object is using a spy but I recommend you to not use them, or even to not think about them unless you're fighting with some ugly legacy code. I think your second 'when' should be replaced with assertion, like:

    assertFalse(mockProductManager.isTempProduct(p1));
    

    because what you really want to check in this test is if productManager.isTempProduct(p1) returns false for all instances of PermProduct. To verify results of some method calls/objects states you should use assertions. To make your life with assertions easier you can take a look on some helpful libraries like Hamcrest or FEST (http://docs.codehaus.org/display/FEST/Fluent+Assertions+Module). FEST is simpler for beginners I think.

    Thanks for your response. I updated my questions. What I really want to test is not the TempProduct, it is actually products method referencing it.What I don't understand is why the exceptino is not thrown at the first when statement. – user3123690 Apr 7, 2014 at 14:23 Hey read my answer one more time please, mockProductManager is not a mock that's why you get this exception. You cannot use not mock object in when statement. Your 'ProductManager' object is an instance of class under testing and what you want to achieve with your test is that this class under test behaves correctly. To verify that your class works correctly you are using assertions. To verify that your class cooperates correctly with other components (mocked while testing) you should use Mockito.verify() – enterbios Apr 7, 2014 at 16:02 You were right. I was trying to partially mock some methods in the class under test. But it would be nice to mock some methods in the class under test since these methods contain legacy code. Could you show me how to partially mock a method in the class under test using Mockito? – user3123690 Apr 7, 2014 at 20:16 docs.mockito.googlecode.com/hg-history/… read more about spying here. Indeed it is used for working with legacy code and if you need to use it with any fresh code probably you have a design problem. – enterbios Apr 7, 2014 at 20:25 Thanks for the link and the idea that we can do partial mock, but I wouldn't abuse it as you said since this is sign of design issue. I found this link very helpful. gitshah.com/2010/05/how-to-partially-mock-class-and-its.html. I was able to implement test in two ways. One is without partial mock and the other way was with the partial mock. I found the partial mock is very concise. – user3123690 Apr 7, 2014 at 21:27

    Thanks for contributing an answer to Stack Overflow!

    • Please be sure to answer the question. Provide details and share your research!

    But avoid

    • Asking for help, clarification, or responding to other answers.
    • Making statements based on opinion; back them up with references or personal experience.

    To learn more, see our tips on writing great answers.