The layout is that a method call was made during a unit test, but doesn’t actually call it

I am writing a JUnit test as well using Mockito, and I want to call a method, which in turn calls the second method several times. I don't want this second method ever to be called during my unit test, but I want to know what its arguments would be. My testing code looks something like this:

public class MyClass { public void myMethod() { int a = [do some logic] int b = [do some logic]; doSomething(a, b); a = [do some logic]; b = [do some logic]; doSomething(a, b); } public void doSomething(int a, int b) { // code that I do not want to be executed during a unit test } } 

And now unit test:

 @Test public void test() { MyClass myClass = new MyClass(); myClass.myMethod(); verify(myClass).doSomething(17, 33); verify(myClass).doSomething(9, 18); } 

I'm new to Mockito, and I don't know if it is possible A) to prevent doSomething () and B) from checking the values ​​of a and b. I am ready to accept answers such as "Mokito cannot help you here" or "this is not technically possible." If there is no way to mock it, I can consider reorganizing the blocks [to make some logical ones] into methods that I can test directly, but my code is more complex than this simple example, and I am not allowed to publish the code on the Internet.

+4
source share
2 answers

Spies are ugly. If you partially mock the class you're testing, you can easily get confused about what is being taunted and what is really being tested. Mockito Javadoc clearly warns against partial bullying.

Better reorganize your code so you can test it cleanly. Extract doSomething() into a new class:

 public class SomethingDoer { public void doSomething(int a, int b) { // code that you do not want to be executed during a unit test } } 

Changed MyClass:

 public class MyClass { private final SomethingDoer somethingDoer; public MyClass(SomethingDoer somethingDoer) { this.somethingDoer = somethingDoer; } public void myMethod() { int a = [do some logic] int b = [do some logic]; somethingDoer.doSomething(a, b); a = [do some logic]; b = [do some logic]; somethingDoer.doSomething(a, b); } } 

Test:

 @Test public void test() { SomethingDoer somethingDoer = mock(SomethingDoer.class); MyClass myClass = new MyClass(somethingDoer); myClass.myMethod(); verify(somethingDoer).doSomething(17, 33); verify(somethingDoer).doSomething(9, 18); } 
+5
source

To do this, you need a partial Mockito layout .

This has not been verified, but I think that what you want may be something like:

 @Test public void test() { MyClass myClass = spy(new MyClass()); doNothing().when(myClass).doSomething(any(Integer.class), any(Integer.class)); myClass.myMethod(); verify(myClass).doSomething(17, 33); verify(myClass).doSomething(9, 18); } 

spy sets up a partial layout so that you can replace some methods and use some real methods. doNothing drowns out your doSomething (an interesting coincidence of names) to do nothing instead of invoking real code.

+5
source

Source: https://habr.com/ru/post/1394520/


All Articles