[rspec-users] Can I do foo.should (be_nil || be_empty) in rspec

Ashley Moran
2008-11-04T13:53:57Z

On 4 Nov 2008, at 12:45, Andrew Premdas wrote:

> General case I''m thinking about is just testing that something
> should be one thing or another
>
>    e.g x.should be(foo || bar)
>
> Haven''t got a specific example at the moment apart from the blank
> one.  What I''m thinking about is the syntax to say this in a spec,
> as I think there must be lots of times when having this sort of
> syntax would be useful.

Hi Andrew

I suspect that in general the concept of an object O being (foo ||
bar) actually means there''s a rule that makes your object baz
instead.  The reason is that if you spec foo and bar independently,
you double the number of contexts for objects that depend on O.

So this might not look to bad:

   describe MyObject do
     before(:each) do
       @o = MyObject.new
     end

     it "should be foo or bar" do
       @o.should be_foo_or_bar
     end
   end

but it means everywhere else you''re forced to duplicate that logic, eg:

   describe MyOtherObject do
     describe "when its MyObject is foo" do
       before(:each) do
         o = mock(MyObject, :foo => true, :bar => false)
         @oo = MyOtherObject.new(o)
       end
       it "should be faz" do
         @oo.should be_faz
       end
     end

     describe "when its MyObject is bar" do
       before(:each) do
         o = mock(MyObject, :foo => false, :bar => true)
         @oo = MyOtherObject.new(o)
       end
       it "should be faz" do
         @oo.should be_faz
       end
     end

     describe "when its MyObject is neither foo nor bar" do
       before(:each) do
         o = mock(MyObject, :foo => false, :bar => false)
         @oo = MyOtherObject.new(o)
       end
       it "should not be faz" do
         @oo.should_not be_faz
       end
     end
   end

instead of just:

   describe MyOtherObject do
     describe "when its MyObject is baz" do
       before(:each) do
         o = mock(MyObject, :baz => true)
         @oo = MyOtherObject.new(o)
       end
       it "should be faz" do
         @oo.should be_faz
       end
     end

     describe "when its MyObject is not baz" do
       before(:each) do
         o = mock(MyObject, :baz => false)
         @oo = MyOtherObject.new(o)
       end
       it "should not be faz" do
         @oo.should_not be_faz
       end
     end
   end

s/foo/nil/
s/bar/empty/
s/baz/blank/

This make sense?  Sorry if it''s a bit abstract, or has typos.  I
didn''t actually run that code, of course...

I think in summary, two branches in your specs => you are violating
Tell Don''t Ask (somewhere else) in your code.

Ashley

--