I'm trying to figure my way around mocking this guy. I have Mockito blessed through Surefire:
@Inject
private javax.ws.rs.client.Client client;
...
String response = client.target(url).request(MediaType.APPLICATION_JSON).post(Entity.entity(request, MediaType.APPLICATION_JSON), String.class);
Results in some really awful mocking:
doReturn(mockWebTarget).when(mockClient).target(url);
doReturn(mockBuilder).when(mockWebTarget).request(MediaType.APPLICATION_JSON);
doReturn(response).when(mockBuilder).post(any(Entity.class), eq(String.class)); // <- really need to inspect that entity
client is injected (Spring). no problems at runtime, but pain in test.
- boilerplate rest client chain
- have to verify a nested object to post()
- prefer to avoid chaining mocks
- chain has multiple classes (i.e., not a typical builder)
- chained mock failures just give a null pointer exception to diagnose
- fragile to maintain and unhelpful when it fails
My main problem is if there is any problem, it just throws nulls when a mock return fails and i dereference in the chain.
Is there a good pattern for this?
- edit -
Fished my wish
Discovered Captors and I think I get the philosophy now.
The approach is to get through the chain with a lot of any() matchers. This basically collapses the chain call so I can worry about entry and exit points.
Then I can retroactively capture the end of the chain with verify() and captors to inspect the post() in the middle after the fact, and just beat the heck out of it.
There was also an opportunity to look at arguments added in the chain and try and reduce them - in my case I could replace post(entity,String.class) with postJson(entity). Didn’t even know the alternative existed.