Question

Recently, I've been reading a lot of articles (mostly from J.B. Rainsberger) about contract and collaborative tests. In order to get it into it, I've started a small project.

From my understanding, the responsiblity of a contract test is to ensure that an implementation respects its interface inherent contract. In other words, it encourages the Liskov substitution principle.

Mocking an objects collaborator is, basically, all about making assumptions about it. Now, what happens if these assumptions change? If I mock the collaborator using Mockito like this (which comes to the same thing as stubbing):

 when(collaborator.doSomething(someArgument)).thenReturn(someValue);

I won't be able to notice the changes when I'll modify the collaborators interface (that is, its contract).

So here's my question : Is it right that when faking a collaborator which provides indirect inputs to a system under test, one should use stubs in order to prevent unnoticed interface / contract changes?

Here are some links that I've already checked:

removing-the-integration-test-scam-understanding-collaboration-and-contract

writing contract tests in java differently

I hope I'm clear enough, if not, I'll do my best to make this more transparent. Thanks to you all in advance.

Était-ce utile?

La solution

there is a clear separation between Stubs and Mocks.

A stub is a stand-in and cannot change the outcome of the test. For example, an input parameter that is passed into the subject.

A mock on the other hand can fail a test. It is the basis for the testing the collaboration between objects. If the expected collaboration is not met, the test should fail.

So in the context of your question, indirect inputs into a system should be stubs.

Autres conseils

JB Rainsberger has an article that seems to precisely answer your question : Who Tests The Contract Tests ?

So here's my question : Is it right that when faking a collaborator which provides indirect inputs to a system under test, one should use stubs in order to prevent unnoticed interface / contract changes?

Use stubs as opposed to what ?

Mocks ? That doesn't make a big difference, and stubs are more appropriate in that kind of situation anyway, as pointed out by @bryanbcook .

Manual fake classes that don't even implement the same base class as the collaborator ? Sure.

IMO there are 2 kinds of contract changes :

  • "Hard" changes, i.e. changes in the return type or parameter types of your collaborator's method. These modifications are easy - they can't go unnoticed as your tests won't even compile any more, provided your fake collaborator implements the same interface/base class as the real collaborator.

  • "Soft" changes, i.e. changes in the conditions under which the collaborator returns a given value or another, changes in the range of values the collaborator can return or accept, in the exceptions that could be thrown, etc. These are more difficult to spot but according to the aforementioned article, they could be avoided by enforcing a strict correspondence between contract tests and collaboration tests.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top