Testing model state: look into db or make use of appropriate methods?

So, I want to test how my model Queue performs adding an Item. I need to complete the following steps:

  • Clear the entire queue
  • Add an item into the queue
  • Look for the item in the queue

The queue uses MongoDB internally.

It seems I have the following options:

(a) Clear the queue's collection executing an appropriate MongoDB command (db.queue.remove()), call queue.add (item), then check the colleciton state (db.queue.find() or db.queue.find());

(b) Clear the queue with queue.clear(), then call queue.add(item), then check queue.count().

What is the difference between theese options and what are the reasons to choose one of them instead of another? (a) looks more "functional" but introduces some brittleness and code duplication among code and tests (is this an issue, btw?), but (b) makes me feel I test everything but nothing special at the time.

Use (b). Your unit tests should not make assumptions about the internal implementation details of the class under test. "Test behavior, not implementation". Using (a) will result in brittle tests that may fail if the internal implementation changes.

Finally I ended with the following.

The (a) and (b) approaches differ in coupling to the SUT. The (a) is less coupled and this is the round-trip test, and the (b) is tightly coupled and thus it's a layer-crossing test.

The first one follows the so called Use the Front Door First Principle, the second follows the Back Door Manipulation Principle.

The first approach focuses on the public contract of the class. The second - on its implementation.

We need both kinds of tests. The first to develop the interface of the class, the second - to drive its implementation.

More details on importance of the stong separation of these kinds of tests could be found in this nice article.