Picture of stu

What is odd about these tests?

  • Posted By Stuart Halloway on June 01, 2008

Question: What is unusual about this test?

expect false do
  validation = Validatable::ValidatesLengthOf.new 
               stub_everything, 
               :username, :maximum => 8
  validation.valid?(stub(:username=>"usernamefdfd"))
end

Answer: They are anonymous. Jay Fields has written about why this might be a good idea, and included feedback from a bunch of people who care about this kind of thing.

The example above is from tests in Jay's validatable library. Here is a modified version of the same test:

account = Struct.new(:name)
expect false do
  validation = ValidatesLengthOf.new account, 
               :name, :maximum => 8
  validation.valid?(account.new("this string is too long"))
end

The modified version changes several things:

  • Rather than a stub, a named struct makes the test look more like a real-world usage.
  • Including Validatable at the top of the module (not shown) keeps namespaces out of the test.
  • Test strings can have values that name their purpose, e.g. "this string is too long".

Much food for thought here. How would you answer these questions?

  • Do you prefer the stub or the struct version? Do anonymous tests change your ideas about when to stub? How?
  • Struct.new is more typical of real-world usage than a stub would be. A named class would be even more typical. Why would using a named class be a bad idea in languages like Ruby and Java, and what features would a language need to fix the problem?
  • Do the string names make the test more readable? Do they re-introduce the problem Jay was solving in the first place?
Comments
  1. Jay FieldsJune 02, 2008 @ 08:34 AM

    Hello Stu,

    I would actually rewrite the test like the one below.

    Expectations do expect Validatable::ValidatesLengthOf.new(stub_everything, :name, :maximum => 8).not.to.be.valid?(stub(“account”, :name => “a string that’s too long”)) end (pastie version available: http://pastie.caboo.se/207099)

    It’s quite long, but it gets everything I need done on one line, which is nice.

    I like the descriptiveness of naming the struct, but I’d probably just go with a named stub (like my example) it gives me the readability while allowing me to define the duck in the test. I like this approach because when the test breaks, I won’t need to look anywhere to find something defined outside the test.

    I don’t see how Struct.new is more of a real-world usage. Aren’t they both just ducks that respond to .name ? I avoid a named class so I can encapsulate all I need for the test within the test. I could also define a named class within the test, but that would take more lines and is more than what’s required (imo). All I need is a duck that responds to .name.

    The string name is a good change and do make the test more readable in my opinion.