Elementary Tests

2.1 Test your Equals method

Java has two forms of equality, corresponding to eql? and equals? in Ruby. Ruby additionally has two more forms of equality, == and ===. As far as I can tell the follow contracts for each are expected:

equals?
This only means object identity. As is it is also unchangeable, it will never need to be tested
eql?
Requires that the both objects have the same type and "equal values." The relationship is expected to be reflexive, symmetric, and transitive. Furthermore if a.eql? b then it is assumed that a.hash == b.hash.
==
Assumes that the two objects represent the same value, but does not require that hashes are equal or that the classes match (i.e., 1 == 1.0). The probable contract is that the relationship is reflexive, symmetric, and transitive and that if a.eql? b then a == b.
===
Used to indicate matches within a when clause of a case statement. This relationship can be much weaker — I haven't found an implied contract besides reflexivity. In particular a === b does not mean that b === a.

The recipe noted in Junit Recipes applies pretty closely to a test of a modified eql? method. I have yet to find tool equivalent to EqualsTester — I may write one myself.

2.2 Test a method that returns nothing

This recipe is virtually identical to the one in JUnit Recipes (namely test the side effects). The example code from the book can be written in Ruby as follows:

class AddToArrayTest < Test::Unit::TestCase def test_array_add array = [] assert !array.include?('hello') array << 'hello' assert array.include?('hello') end end

2.3 Test a constructor

Again the general points made in JUnit Recipes apply to Ruby as well. The book show tqo examples (outside of the discussion), one where the constructor is checked using properties, and one where the constructor is checked using a validation method. See the section Testing-only attributes

Check using attributes
def test_initialization_attributes value = Complex.new(3, 10) assert_equal 3, value.real assert_equal 10, value.image end
Check using validator
def test_initialize_with_valid command = BankDepositCommand.new("123", 125.dollars + 50.cents, Time.now) assert command.valid? end