0

I have MyClass that has OtherClass as a field:

public class MyClass
{
    @Autowired
    private OtherClass other;
    public void foo() {
        // Some interactions
        other.bar(someParameter);
    }
}

public class OtherClass
{
    public void bar() {
        // Some interactions
        if (someConditionThatIsTrue) {
            baz(someParam);
        }
    }

    public void baz(SomeParamClass param) {
        // Some interactions
    }
}

For testing MyClass, I want to check that OtherClass.baz() was called from MyClass.foo(). This is what I have:

@RunWith(MockitoJUnitRunner.class)
public class MyClassTest {
    @InjectMocks
    private MyClass myClass;
    @Mock
    private OtherClass otherClass;

    @Test
    public void testFoo_whenFooIsCalled_shouldTriggerBaz() {
        // Some setups
        myClass.foo();
        verify(otherClass, times(1)).baz(any());
    }
}

The test above doesn't detect OtherClass.baz(), but detects OtherClass.bar() :

Wanted but not invoked: otherClass.baz( <any> ); -> at MyClassTest.testFoo_whenFooIsCalled_shouldTriggerBaz(MyClassTest.java:12) However, there were other interactions with this mock: otherClass.bar( "some parameter" ); -> at MyClass.foo(MyClass.java:7)

Without refactoring MyClass, is it possible to detect the instance of OtherClass.baz() from the test?

Caladbolgll
  • 400
  • 1
  • 3
  • 15
  • 2
    There was no call to `baz`. Your `OtherClass` instance is a mock so it does not run the code from your implementation. – Erwin Bolwidt Apr 16 '19 at 00:48
  • @ErwinBolwidt Is the current solution a bad practice for unit testing design? What would you recommend as an alternative? – Caladbolgll Apr 16 '19 at 06:29

1 Answers1

1

You just need to use a spy

@Spy
private OtherClass otherClass;

However, this isn't a great practice. You're testing two distinct classes. I would just make sure you make the call to bar in your first test with the correct param. Then create a separate unit test file for OtherClass.

DCTID
  • 1,277
  • 9
  • 13