2

I'm writing a test for my server with Mockito. In my test, instead of a real Messenger (which would try to send actual HTTP messages to a client), it uses a mock Messenger. The problem I'm facing is, one of the server methods basically does this (in a thread created by the server, not the test thread):

void serverMethod() {
  MyObject object;
  object.setProperty(1);
  messenger.send(object);
  object.setProperty(2);
}

And in my test, I'm trying to verify that object.getProperty() would return 1 at the time it's passed to messenger.send(), not 2. I've tried both custom argument matchers and argument captors, and both actually pass some of the time, but they don't pass reliably because the test thread is racing against the server thread which is about to modify "object" so that object.getProperty() returns 2.

I've already verified that the app code doesn't have an actual bug, because the real Messenger immediately serializes "object" to send to the client, effectively copying the value of "property" so any later modifications don't matter.

I'm well aware that this may be one of those instances when, although the app code is working fine, it has poor testability, so the only way to write a good deterministic test for this (without changing the whole testing infrastructure) is to modify the app code to improve testability (in this case, passing an immutable object instead of this mutable one that's about to be modified and reused).

My question is, is there any clever way to properly test this without touching the app code?

Keenan Pepper
  • 321
  • 1
  • 3
  • 10
  • What happens with the `object` after the property has been set to `2`? – second Aug 07 '19 at 07:07
  • In the actual server code, it's setting the property and then calling messenger.send() within a loop. The property is later set to different values in later loop iterations. – Keenan Pepper Aug 07 '19 at 16:20
  • 1
    You could implement a custom `ArgumentMatcher` that makes a `deepcopy` of the object inside and stores it for you to verify it later. Or you define specific behaviour definitions for every method invocation that compares the actual content (could be done by implementing proper `equals` and `hashCode` methods), later you could use `verify` mabye in combination with `inorder`. I can not really say what would be a proper solution without seeing a more complete example. – second Aug 07 '19 at 18:49

0 Answers0