Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Behavior vs. State Based Testing

I know this question is part of a bit of a religious war, but I have the following situation: I have an object, Responder that calls a method on object Updaterin response to different events. I recently separated the testing in this way: state-based tests for the Updater method itself, and behavior-based tests for the Responder that calls it. That is, I mock the Updater in the Responder tests, just to ensure that it is called.

Should I still be testing the state of the objects that are supposed to be updated in the Responder tests and not mocking the Updater? I like what I have done because it requires less setup and seems to better isolate the tests. However, this seems to tie the implementation and expected behavior of Responder to Updater. Is that too brittle? This is a simplified example.

like image 988
Matt H Avatar asked Aug 18 '10 16:08

Matt H


People also ask

What is testing behavior?

Behavior testing simply means that we should test how an application behaves in certain situations. Often the behavior is given to us developers by our customers. They describe the functionality of an application, and we write code to meet their specifications.

What do you know about state based unit testing?

Verifying that the system under test produces correct results, or that its resulting state is correct, is called state-based unit testing, while verifying that it properly invokes certain methods is called interaction-based unit testing.

What is interaction-based testing?

Interaction-based testing is a design and testing technique that emerged in the Extreme Programming (XP) community in the early 2000's. Focusing on the behavior of objects rather than their state, it explores how the object(s) under specification interact, by way of method calls, with their collaborators.

Is implementation same as testing?

Implementation refers to a formulated plan for a designated process. It is important for any process to have a completed plan and clear objectives. The plan usually contains several actions that need to be carried out. Each of these actions needs to be tested, which is called implementation testing.


1 Answers

If I did understand your question correctly you really need at least two levels of testing:

  1. Unit tests, where you are trying to test only one class and mock all the dependencies (so in your case Updater needs to be mocked here). These tests help you develop the code (especially if you are using TDD), make sure the class behaves as designed and even document how this class is meant to behave. Pretty much every class should have unit tests. However, as you noticed even if you have 100% test coverage you have no guarantee that your program works or even starts up!

  2. Acceptance, integration and end-to-end tests - these tests cover either the whole application or big modules and test that everything works together. In general you don't use mocks at this level (you might stub a whole module/web service though, depending on the context). These tests don't have to test every single implementation detail (and shouldn't), because this is done by unit tests. They make sure that everything is correctly wired and working together. In your case you wouldn't mock Updater here.

So to sum up I think you really need to do both to have your application properly tested.

like image 66
Grzenio Avatar answered Sep 29 '22 05:09

Grzenio