views:

85

answers:

3

So I'm fairly new to ruby in general, and I'm writing some rspec test cases for an object I am creating. Lots of the test cases are fairly basic and I just want to ensure that values are being populated and returned properly. I'm wondering if there is a way for me to do this with a looping construct. Instead of having to have an assertEquals for each of the methods I want to test.

For instace:

describe item, "Testing the Item" do

  it "will have a null value to start" do
    item = Item.new
    # Here I could do the item.name.should be_nil
    # then I could do item.category.should be_nil
  end

end

But I want some way to use an array to determine all of the properties to check. So I could do something like

propertyArray.each do |property|
  item.#{property}.should be_nil
end

Will this or something like it work? Thanks for any help / suggestions.

+4  A: 

object.send(:method_name) or object.send("method_name") will work.

So in your case

propertyArray.each do |property|
  item.send(property).should be_nil
end

should do what you want.

sepp2k
Thanks! I knew there had to be a way to do it.
Boushley
+1  A: 

If you do

propertyArray.each do |property|
  item.send(property).should be_nil
end

within a single spec example and if your spec fails then it will be hard to debug which attribute is not nil or what has failed. A better way to do this is to create a separate spec example for each attribute like

describe item, "Testing the Item" do

  before(:each) do
    @item = Item.new
  end

  propertyArray.each do |property|

    it "should have a null value for #{property} to start" do
      @item.send(property).should be_nil
    end

  end

end

This will run your spec as a different spec example for each property and if it fails then you will know what has failed. This also follows the rule of one assertion per test/spec example.

nas
A: 

A couple points about Object#send()...

You can specify parameters for the method call too...

an_object.send(:a_method, 'A param', 'Another param')

I like to use this other form __send__ because "send" is so common...

an_object.__send__(:a_method)
Ethan