0

Is there any way to verify whether the b.method1() is the last method called? Another problem is that at the stage of test development I cannot know exactly which methods are called before this one. I am using Mockito, PowerMockito and Junit. inOrder can not be used here! 1st reason - i have private methods. All public here for good example. 2nd reason - i don't know even amount of method, that can be called before b.method1().

Testing classes:

public class Test{

    public static void main(String[] args) {
            A a = new A();
            B b = new B();
            a.method2();
            a.method3();
            b.method2();
            b.method1();
        }
}



public class A{

    public void method1(){}

    public void method2(){}

    public void method3(){}
}



public class B{

    public void method1(){}

    public void method2(){}

    public void method3(){}
}
A. Kashnikov
  • 143
  • 2
  • 11
  • 1
    Possible duplicate of [Mockito verify order / sequence of method calls](https://stackoverflow.com/questions/21901368/mockito-verify-order-sequence-of-method-calls) or [Mockito verify the last call on a mocked object](https://stackoverflow.com/questions/50503729/mockito-verify-the-last-call-on-a-mocked-object) – Anthony Raymond Dec 04 '18 at 14:19
  • @AnthonyRaymond, inOrder can't be used here. Because i don't know which methods will called. – A. Kashnikov Dec 04 '18 at 14:22
  • Take a look at the second link then, use `inOrder.verify(b).method1();` followed by `Mockito.verifyNoMoreInteractions(b);` and don't add multiple lines to the inOrder, that you you won't care about other methods order. Note that B instance must be a mock or a spy in your test – Anthony Raymond Dec 04 '18 at 14:24
  • 1
    Beyond that: you are trying to fix a design problem using testing. A good interface makes it easy to do the right thing, and hard to do a wrong thing. When your internal logic requires that methods get called in a specific order ... then you force your client code to **know** about that order. So, the real world answer here: step back, and consider to change your interface in ways that dont create such *implicit* contracts to follow. – GhostCat Dec 04 '18 at 14:30
  • @AnthonyRaymond, before using `Mockito.verifyNoMoreInteractions(b);` , i have to verify all methods of mocks. But i cant do this, because i am not sure, that all methods will called – A. Kashnikov Dec 04 '18 at 14:32
  • @GhostCat Thanks for good advice, but feature of my project is to automatically test solutions of another developers. So i cant rebuild their interface. I just can find verification mistakes. – A. Kashnikov Dec 04 '18 at 14:36
  • 1
    Different story then. What about https://stackoverflow.com/questions/53614921/how-to-verify-it-was-the-last-method-called ... does that help? Beyond that, another solution would be to use create your own "stub" classes, that simply do such checking "inside" themselves. But that would requires that A and B could be extended, all methods overridden, and also to get those calls to `new` away. – GhostCat Dec 04 '18 at 14:42
  • @GhostCat, no that does not. Yes, maybe, to create own stub is the only one solution. Do you know, maybe, Mockito provide their any interface for stub creating and using? – A. Kashnikov Dec 04 '18 at 14:45
  • Not that I am aware of ... there is the Mockito Spy, but I doubt that helps here. – GhostCat Dec 04 '18 at 14:55

1 Answers1

0

You mention 2 problems that block you from using inOrder

  • you don't know which methods have been called before
  • you have private methods

None of these 2 are valid reasons. It is always possible to use inOrder.

Whatever your method needs to do should depend on 2 things only:

  • The parameters passed to the method.
  • State. And in a well designed class that should be restricted to the state of the object who's method you are calling.

Any possible combination of data in the parameters and the state of the object can be simulated using mockups. And anything that happens inside your method (method calls being done) should be known by you, otherwise you would not know what you are trying to test.

So, if any methods, private or not were called before, there are 2 possibilities:

  • It has impact on your method. In that case it should be visible in the state of the object and you can initialize your test object and your mockups differently in multiple test cases to test the different possibilities.
  • It has no impact on your method. In that case, it obviously can't be a problem for your test.

The only situation where you can have some trouble is when static methods of other classes are called directly or static fields are read directly and their state can have impact. In those cases, it is best to isolate such calls in a separate method in a class that doesn't contain much logic and acts as a wrapper. That way you have a wrapper which you can mock and that solves the problem.

A special case are constructors which are called. A constructor is a special sort of static method. And the above mentioned approach for statics corresponds to creating a factory class to construct the objects. But a constructor creates something that didn't have a state yet. And that means it's state can not be unpredictable/problematic for your test. But even then a factory that can be mocked can be very useful to avoid unnecessary complexity and dependencies in tests.

Conclusions:

When you know what your method is doing and it doesn't use statics from other classes directly, you can always check everything using inOrder and add a call to verifyNoMoreInteractions in the end to make sure the last method you verified was the last one that was called.

And even when it does use statics from other classes directly which complicate your tests, that is a design issue that can easily be solved.