1

Main Class

public class BootSample {

    public int call(int m) {
        System.out.println("Entering into Call Method");
        int n = m*10;
        TestUtil testUtil = new TestUtil();
        testUtil.add(m, n);
        System.out.println("End of Call Method Value n : " + n);
        return n;
    }

}

Util Class

public class TestUtil {

    public void add(int a, int b) {
        System.out.println(" Entering into TestUtil Method ");
        int c = a +b;
        System.out.println(" End of TestUtil Method Value : " + c);
    }

}

Test Class

@RunWith(MockitoJUnitRunner.class)
public class BootSampleTest {

    @Mock
    TestUtil testUtil; 

    @Before
    public void setup() {

    }

    @Test
    public void utilSuccess() throws Exception {
        BootSample bootSample = new BootSample();
        doNothing().when(testUtil).add(any(Integer.class),any(Integer.class));
        int result = bootSample.call(10); 
        assertEquals(result,100);
    }

}

Output :

Entering into Call Method
 Entering into TestUtil Method 
 End of TestUtil Method Value : 110
End of Call Method Value n : 100

I'm trying to mock util void method call with doNothing but doesn't work.Can anyone please help me with solution? I'm stuck with similar functionality in our application.

Timothy Truckle
  • 15,071
  • 2
  • 27
  • 51
chebs
  • 13
  • 1
  • 1
  • 3

3 Answers3

2

The problem is that your call method is responsible for creating a TestUtil object, and that object can't be mocked. Try adding TestUtil as a constructor argument like so:

public class BootSample {

    private TestUtil testUtil;

    public BootSample(TestUtil testUtil) {
        this.testUtil = testUtil;
    }

    public int call(int m) {
        System.out.println("Entering into Call Method");
        int n = m*10;
        testUtil.add(m, n);
        System.out.println("End of Call Method Value n : " + n);
        return n;
    }
}

You then need to mock the TestUtil class and pass the mock to the BootSample class:

BootSample bootSample = new BootSample(testUtil);
Eric
  • 2,008
  • 3
  • 18
  • 31
  • public class BootSample { public BootSample(Object mac) { this.mac = mac; } public int call(int m) { System.out.println("Entering into Call Method"); int n = m*10; TestUtil testUtil = new TestUtil(); testUtil.add(m, n); System.out.println("End of Call Method Value n : " + n); return n; } } Caller BootSample bootSample = new BootSample(macObject); bootSample.call(15); – chebs Jan 11 '18 at 21:12
  • Thank You @Eric .This works but I have another main constructor which accepts some value where i cannot create new constructor of BootSample with testUtil. Is there any alternative approach ? like above – chebs Jan 11 '18 at 21:12
  • If you can't add the `TestUtil` object to a new constructor or an existing constructor, then you could just set the `TestUtil` object using a setter and calling it. Somehow you're going to have to inject the mock, whether it is through a constructor or a setter. – Eric Jan 11 '18 at 22:41
  • Thank You very much.Can you explain little more on using setter that would be great help.Really appreciate your help.Thanks a ton. – chebs Jan 12 '18 at 19:27
1

If you're seeing the System.out.printlns from your TestUtil class then it isn't mocked. It looks like you're missing the @InjectMocks on BootSample to tell Mockito to inject your mocked TestUtil into it.

See the example in the docs here: http://static.javadoc.io/org.mockito/mockito-core/2.13.0/org/mockito/InjectMocks.html

Kevin Hooke
  • 2,583
  • 2
  • 19
  • 33
  • 2
    If you use `@InjectMocks`, the `TestUtil` needs to be injected in your production as well, of course. – Johannes Jasper Jan 10 '18 at 22:37
  • The `@InjectMocks` approach has the disadvantage that you can declare more mocks but "forget" to add them to the constructor parameters. Your test does not get a compile error. And by the rules of *TDD* you are not allowed to change the production code then... – Timothy Truckle Jan 10 '18 at 22:51
  • 1
    Thank You Kevin for your input it was really helpful. – chebs Jan 17 '18 at 16:25
1

You can use Mockito.anyInt() instead of Integer.class, code example :

Mockito.doNothing().when(testUtil).add(Mockito.anyInt(),Mockito.anyInt());
Stefan Birkner
  • 24,059
  • 12
  • 57
  • 72