Forum: RSpec customize description and failure messages when writing rspec matcher dsl

Posted by Anran Yang (Guest)
on 2011-11-24 08:11
Attachment: Screenshot.png (5,12 KB)
(Received via mailing list)
_______________________________________________
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users
Posted by David Chelimsky (Guest)
on 2011-11-24 17:26
(Received via mailing list)
On Nov 24, 2011, at 12:48 AM, Anran Yang wrote:

>     should be_structured_as(
>         :can_be_a => {
>                     :parallel_programming_model,
>                     :description
>         }
>     }})
>   end
> end
>
> ===========================================
>
> The purpose is to test the entire model structure(attributes, inheritance and 
association).

Then term Behavior Driven Development came into being, in part, to 
discourage this approach to testing. We believe testing should be about 
behavior, and that testing structures leads to highly coupled tests that 
are hard to change.

I'd recommend thinking about the need for each of these attributes, come 
up with examples of how they are used and write those instead. That 
said, see below for more on how matchers work.

>       obj = Factory.create(klass)
>   end
> end
>
> ===============================================
>
> To simplify the matcher definition,  I used some other machers like "obj.should 
have_these_attributes (desc[:has] ||= [])", this works fine, thanks to the 
excellent new matcher dsl syntax. Howerver, I got trouble when running the test 
using "rspec spec/models/hpgc_spec.rb -fd". The test passed but print
>
> <Screenshot.png>
>
> instead of something like "Hpgc should be structured as ...". I think it may due 
to the other matcher I used because the message is from the matcher 
"have_these_attributes".

That's correct. The default behavior is that the block passed to the 
"match" method in the matcher DSL is expected to return a boolean. If it 
raises an exception instead, that exception bubbles up and becomes the 
source of the failure message.

> I try to add method "description" but seems it doesn't work.

"description" is used for the documentation formatter, not for failure 
messages. If you run "rspec spec --format documentation" you'll see 
names for all your examples.

> And the failure message is also a problem. I search the web and come across some 
solutions, but all of them need manually build the message. I've not come out a 
clean way to do this(I must add some invasive clauses to track the error) and 
think maybe the best behaviour would be that it "throw" the failure message of 
inner matchers or false-value expressions. But this time it just told me something 
like "Hpgc is expected to be structured as ...".

Instead of using the "match" method in the matcher, you can use 
"match_unless_raises", which returns false if it captures an exception, 
letting the matcher control the failure message (which is what I think 
you're looking for):

RSpec::Matchers.define :be_structured_as do |structure|
  def check(namespace, klass, desc)
    # ....
  end

  match_unless_raises do |namespace|
    self.class.send :include, namespace
    structure.each { |key, value| check namespace, key, value }
  end
end

HTH,
David
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.