Test Smells

Flashcard 3 of 5

Keeping our last flashcard in mind, what jumps out at you about this code?

describe PrefixedLogger do
  describe "#log" do
    it "adds a prefix to logged messages" do
      logger = double("logger")
      expect(logger).to(
        receive(:log).with("PREFIX: message")
      )
      prefixed = 
        PrefixedLogger.new(logger, "PREFIX: ")

      prefixed.log("message")
    end
  end
end

If you said "that code relies on a message expectation and therefore lacks a Verify phase!" then consider us super impressed. More on this in a second.

If you are instead saying "what the heck is a method expectation?!", don't panic! Just check out [this rspec documentation on method expectations][] and come back when you've got the gist.

If you're super confused in general, continue to not panic. Maybe just save this card for later review and come back when you've got a little more experience.

If you're still with us, notice that by relying on a message expectation like we've done here, the Verify phase has effectively disappeared (the expect does appear, but during the Setup phase). By the way, you might hear this described as mock-based testing (logger is a mock, a type of [test double][]).

Because we like our tests to follow the four phases, we'd probably write the test using a spy instead:

describe PrefixedLogger do
  describe "#log" do
    it "adds a prefix to logged messages" do
      logger = double("logger")
      logger.stub(:log)
      prefixed = PrefixedLogger.new(logger, "PREFIX: ")

      prefixed.log("message")

      expect(logger).to(
        have_received(:log).with("PREFIX: message")
      )
    end
  end
end

Praise the return of the Verify phase!

[this rspec documentation on method expectations]: https://www.relishapp.com/rspec/rspec-mocks/v/3-3/docs/basics/expecting-messages [test double]: http://googletesting.blogspot.com/2013/07/testing-on-toilet-know-your-test-doubles.html

Return to Flashcard Results