Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What should be mocked for an integration test?

Upon reading Growing Object Orientated Software Guided by Tests, I learnt of test isolation and test fragility. The idea that each test should be very specific to a piece of code or functionality, and the overlap of code coverage by tests should be kept to a minimum. The implied ideal that each change in the code should result in breaking only one test. Avoiding spending time going through multiple broken tests to confirm that one change is the cause and if it is fixed by the test modifications.

Now this seems easy enough for unit tests, they are very isolated by their nature. However when presented by integration tests, it seems hard to avoid having multiple tests exercising the same code paths, particularly when run in addition to the unit tests.

So my question, is what dependencies should be mocked when doing integration testing? Should anything be mocked at all? Should a single execution path be tested, and all side effects not directly relevant to this code path be mocked?

I'm toying with the idea of doing pairwise integration testing. Test one relationship between two objects, and mock everything else. Then changes in either one of these objects should have minimal impact on other integration tests, in addition to forming a complete chain of end-to-end tests by means of pairs.

Thanks for any info..

Edit: Just to clarify, I'm basically asking "How do I avoid large numbers of failing integrations tests during the normal course of development?". Which I assume is achieved by using mocks, and why I asked about what to mock.

Update: I've found a very interesting talk about Integration tests by J.B.Rainsberger, which I think answers this fairly well, if perhaps a bit controversially. The title is "Integration Tests are a Scam", so as you can guess, he does not advocate Integration Tests at all (end to end type tests). The argument being that Integration Tests will always be far below the amount needed to thoroughly test the possible interactions (due to combinatoric explosion), and may give a false confidence. Instead he recommends what he calls Collaboration Tests and Contract Tests. It's a 90 min talk and unfortunately the whiteboard is not very clear and there aren't code examples, so i'm still getting my head around it. When I have a clear explanation I'll write it here! Unless someone else beats me to it..

Here's a brief summary of Contract Tests. Sounds like Design by Contract type assertions, which I believe could/would be implemented in a Non-Virtual Interface pattern in C++.

http://thecodewhisperer.tumblr.com/post/1325859246/in-brief-contract-tests

Integration Tests are a Scam video talk: http://www.infoq.com/presentations/integration-tests-scam

Summary:

Integration tests are a scam. You’re probably writing 2-5% of the integration tests you need to test thoroughly. You’re probably duplicating unit tests all over the place. Your integration tests probably duplicate each other all over the place. When an integration test fails, who knows what’s broken? Learn the two-pronged attack that solves the problem: collaboration tests and contract tests.

like image 305
Coran Avatar asked Jul 26 '13 10:07

Coran


1 Answers

For integration tests you should mock the minimum amount of dependencies to get the test working, but not less :-)

Since the integration of the components in your system is obviously the thing you want to test during integration testing, you should use real implementations as much as possible. However, there are some compontents you obviously want to mock, since you don't want your integration tests to start mailing your users for instance. When you don't mock these dependencies, you obviously mock too little.

That doesn't mean btw that you shouldn't allow an integration test to send mails, but at least you want to replace the mail component with one that will only send mail to some internal test mail box.

like image 72
Steven Avatar answered Sep 18 '22 10:09

Steven