I were often asked when to do unit test or integration test, so I decided to write this blog post to clarify:
- it doesn’t talk to database
- it doesn’t communicate across the network
- it doesn’t touch the file system
- Test a single module in isolation. We often use
mockits dependencies. When its tests fail, we know exactly because of itself.
stubobject is a
fake objectand not part of the test. It can be replaced by any other objects.
mockobject is also a
fake object. A
mockobject contains behavior and it is part of what we want to test (collaborator).
1 2 3 4 5 6 7 8 9 10 11 12 13
- The above test would fail if the
#logwith the specified parameter. customer is simply a fake object with no behavior in the test, and it cannot make the test fail. Remember this test is about the logging a message.
- Kind of
White-box testing. It tests internal workings of an application. You dictate the software that it should do this and do that.
private methodsare already tested indirectly by public methods. You should not test it explicitly. However, if you feel that private method is crucious to make your class work correctly, consider give it a better name and promote it as public method.
- Unit tests alone are not enough to make sure the application work correctly.
- Much faster than integration test.
- In Rails, there are functional tests:
controller spec(it touches database).
- It tests interaction between components to make sure these components work nicely with each other.
- Kind of
Acceptance Testing, it focuses on what the user see and how the user interacts with the system. It can be called
Black-box testingwhere we don’t care how it is done. We care only the outcome.
- Much slower than unit test.
- In Rails, it would be request spec and capybara.
1 2 3 4 5 6 7 8 9 10
- The above test send the actual request to
/tasks, fill out the form, and submit. It expects the content we filled out to be display in the page. If it’s a unit test (in this case, functional test aka. controller spec), we would test it differently. We won’t send the actual request, and we would assert it should receive
- It’s better than unit test because it mimics real user behaviors and it tests the entire stack of the application.
- Should we still write controller spec? The answer is
yesfor sad path and leave the happy path in the integration tests. Doing this make your tests a bit faster. Check this blog
Where to get started?
- Should we write unit test first or integration test first? If you haven’t watched this episode from
RailsCasts, watch it. He followed the outside-in development, starting from request spec, controller spec, and model spec.