Problem with mocking a simple has_many relationship

Hi there all. Sorry if the question sounds silly but i’m rather new at
the ‘mocking’ stuff… So here is my problem (code helps more than
talking):

the model:

class Item < ActiveRecord::Base

has_many :images, :dependent => :destroy

protected

def validate
errors.add(:images, “cannot be empty”) if self.images.count
end
end

the spec:

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

it “should have at least one image” do
@item.should have(1).error_on(:images)
@item.images.should_receive(:count).at_least(:once).and_return(1)
@item.should have(0).errors_on(:images)
end
end

Obviously i’m doing something wrong cause this doesn’t work:

‘Item should have at least one image’ FAILED
expected 0 errors on :images, got 1
./spec/models/item_spec.rb:60:
script/spec:4:

Finished in 0.341594 seconds

10 examples, 1 failure, 5 pending

(ignore the rest)

Any help would be more than welcome :slight_smile:

Hi Nikos,

On Tue, Mar 18, 2008 at 8:26 PM, Nikos Dimitrakopoulos
[email protected]
wrote:

the model:
class Item < ActiveRecord::Base
has_many :images, :dependent => :destroy
protected
def validate
errors.add(:images, “cannot be empty”) if self.images.count
end
end

self.images.count is always true, the Fixnum 0 (returned when theres no
images) is true

try on irb: foo = “bar” if [].size

I guess the correct way is errors.add(:images, “cannot be empty”) if
self.images.size < 1

Regards,

On Mar 18, 2008, at 4:26 PM, Nikos Dimitrakopoulos wrote:

describe Item do
end
end

I would try:

it “should have an error with no images” do
@item.should have(1).error_on(:images)
end

it “should be okay with one image” do
@item.stub!(:images).and_return(mock(“images”,:count => 1))
@item.should have(0).errors_on(:images)
end

JD

Ok, i’m really stupid… i was taking a break (i’ve been on the pc for
several hours) and the problem came to me before reading your posts :smiley:
Obviously the “if self.images.count” was waaaayyy too stupid! added the
necessary == 0 and everything is fine…

Thanks a lot anyway :slight_smile:

James D. wrote:

Doh! I can’t believe that I missed that.

You can also use if self.images.size.zero?

Just a little more readable.

James D.

You were writing while i was writing :smiley:

nice one, i didn’t know the #zero? - way more readable :slight_smile:

Doh! I can’t believe that I missed that.

You can also use if self.images.size.zero?

Just a little more readable.

James D.

Ok, last one - for your interest validates_length_of can be used for
this purpose. There is an open bug/patch on the rails trac regarding the
:within parameter but the :minimum works fine for me. As for the example
the method called on @item.images is #size and not #count so
@item.images.should_receive(:size).and_return(1)

P.S.: The bug on the rails trac: http://dev.rubyonrails.org/ticket/11295