0

I'm trying to write a test method that would execute methodA, and want to skip methodB that's being called within methodA. I'm using Mockito's doNothing() to skip methodB, but the methodB is still getting executed.

public class Product extends ParentProduct{
    @Override
    public void methodB(boolean sync) {
        //some code
     }
}

This is the Service class that has method methodA that needs to be tested/executed.

public class Service{
    public Response methodA(Request request) {
         Product product = new Product();
         product.init();
         //want to skip the below line of code that calls methodB
         product.methodB(true);
         Response response = product.getResponse();
         return response;
         }
}

Following is the test method

import org.powermock.modules.junit4.PowerMockRunner;
import static org.mockito.Mockito.*;

@RunWith(PowerMockRunner.class)
public class ServiceTest {
    @Before
    public void setUp() throws IOException {
        MockitoAnnotations.initMocks(this);
    }

    @Mock
    private Product product;

    @Test
    public void testServiceProduct() throws Exception {
        Service service = new Service();
        Request request = new Request();
        doNothing().when(product).methodB(any(Boolean.class));
        Response response = service.methodA(request);
        Assert.assertTrue(response.getMessage().equals("202"));
    }
}

How do I ensure that methodB is skipped and all other lines in methodA are executed? Why is doNothing() not working here? Also I've tried the solution's listed here: Mockito doNothing doesn't work when a Method called with void method call inside Why are my mocked methods not calld when executing a unit test? but this didn't work for me

Dookoto_Sea
  • 521
  • 1
  • 5
  • 16
  • 5
    You're creating a new product in your service;this is where the method is called on. The mocking happens on the mock product you create in the test. – daniu Feb 13 '23 at 07:29
  • Your mock does nothing because it isn't used anywhere. As @daniu said, you're creating a local `Product` inside your method. You need to provide that object from the outside which can then be injected as a mock. – QBrute Feb 13 '23 at 07:51
  • You probably want to factor `Product product = new Product();` out to a separate method, so that you can stub it in a Spy of Service, and make it return your mock Product. – Dawood ibn Kareem Feb 13 '23 at 07:58
  • Also, you're using `product` multiple times in your method. So you either need to mock **all** method calls of that class or make `product` a `Spy`. Otherwise, the test will fail. – QBrute Feb 13 '23 at 08:00
  • I assume it's merely a typo, but `return response();` doesn't use the `response` variable from the previous line. – Andy Turner Feb 13 '23 at 08:20
  • @daniu so I should not create a mock for the Product class? How do I pass the object to doNothing() method in this case? – Dookoto_Sea Feb 13 '23 at 17:39
  • @Dookoto_Sea you're exactly missing the point. Currently, the method you want to test contains a **local** instance of `Product`, which isn't mockable. You definitely want to mock `Product`, but you need to write your class/method in such a way that it becomes *possible*. I.e. don't create a local instance of `Product` inside `methodA` (what does this even do, logically?). Provide a way to inject that product from the outside, e.g. making `product` an instance variable or adding `product` as an argument of `methodA`. – QBrute Feb 14 '23 at 08:52

0 Answers0