Forum: RSpec Does rspec support something like Assumptions in JUnit 4.4?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
mortench (Guest)
on 2009-06-01 14:35
(Received via mailing list)
JUnit 4.4+ has a feature called assumptions and I am looking for
something similar in rspec so that I can express that my examples
require a specific environment variable to be specified for testing to
make sense.

About assumptions from the readme (http://junit.sourceforge.net/doc/
ReleaseNotes4.4.html#assumptions):
"Ideally, the developer writing a test has control of all of the
forces that might cause a test to fail. If this isn't immediately
possible, making dependencies explicit can often improve a design.
For example, if a test fails when run in a different locale than the
developer intended, it can be fixed by explicitly passing a locale to
the domain code.

However, sometimes this is not desirable or possible.
It's good to be able to run a test against the code as it is currently
written, implicit assumptions and all, or to write a test that exposes
a known bug. For these situations, JUnit now includes the ability to
express "assumptions":
"

/Morten
David C. (Guest)
on 2009-06-01 15:00
(Received via mailing list)
On Mon, Jun 1, 2009 at 5:33 AM, mortench <removed_email_address@domain.invalid> 
wrote:
> JUnit 4.4+ has a feature called assumptions and I am looking for
> something similar in rspec so that I can express that my examples
> require a specific environment variable to be specified for testing to
> make sense.

There is no explicit support for this, but you could always just say
(taking the example from the page you cited):

def assume_that(expression)
  yield if expression
end

def verify_that(actual, expected)
  actual.should expected
end

it "should blah de blah" do
  assume_that(File::SEPARATOR == "/") do
    ensure_that User.new("optimus"), eql("configfiles/optimus.cfg")
  end
end

I am planning to add support for something like ensure_that (name up
for grabs) in a future version of rspec, but I'd need to think about
assume_that a bit. We're dealing with Ruby here, not Java, and we
don't suffer things like a 'final' keyword that force us to have to
make assumptions like this. Unless we add some additional feedback,
like "such and such example did not run due to faulty assumptions,"
this seems quite dangerous to me. And even with that, it means that CI
servers are going to pass examples that are never actually run.

HTH,
David
mortench (Guest)
on 2009-06-01 15:14
(Received via mailing list)
Hi David,

Thanks for the suggestion! It indeed make sense for the Junit
example... However, my particular usage case for assumption is a bit
different. I am using jruby+jspec and I have a group of rspec examples
that all require a java property to be set for the examples to be able
to run. Besides, the examples also have an after action that will also
break if the java propety is not set. Idealy, I would like to do
something like.

before(:all) do
    @org_root_prop = java.lang.System.getProperty("root")

    # abort all examples and after action if condition is not meet:
    ensure_that !rootPath.nil? && rootPath.strip.length>0
end

Notice, that the assume is in a before action and not in the examples
themselves + it should affect the examples and after action (none of
which should run if before action assumptions are not meet).

/Morten
mortench (Guest)
on 2009-06-01 15:29
(Received via mailing list)
Correction for last msg:

before(:all) do
    @org_root_prop = java.lang.System.getProperty("root")

    # abort all examples and after action if condition is not meet:
    ensure_that !@org_root_prop.nil? && @org_root_prop.strip.length>0
end

/Morten
Zach D. (Guest)
on 2009-06-01 17:18
(Received via mailing list)
On Mon, Jun 1, 2009 at 7:26 AM, mortench <removed_email_address@domain.invalid> 
wrote:
> Correction for last msg:
>
> before(:all) do
>    @org_root_prop = java.lang.System.getProperty("root")
>
>    # abort all examples and after action if condition is not meet:
>    ensure_that !@org_root_prop.nil? && @org_root_prop.strip.length>0
> end

You could do this check outside of the example? ie:

describe "...." do
   def self.ensure_that(condition, &blk)
      yield if condition
   end

   def self.root_property_is_not_blank
     org_root_prop = java.lang.System.getProperty("root")
     org_root_prop.nil? && org_root_prop.strip.length>0
   end

   ensure_that root_property_is_not_blank do
      it "...." do
      end
  end
end

>
> /Morten
> _______________________________________________
> rspec-users mailing list
> removed_email_address@domain.invalid
> http://rubyforge.org/mailman/listinfo/rspec-users
>



--
Zach D.
http://www.continuousthinking.com (personal)
http://www.mutuallyhuman.com (hire me)
http://ideafoundry.info/behavior-driven-development (first rate BDD
training)
@zachdennis (twitter)
Pat M. (Guest)
on 2009-06-01 20:56
(Received via mailing list)
You can put expectations in your before block, and that'll give you
the behavior you want.

before(:each) do
   @org_root_prop = java.lang.System.getProperty("root")

   @org_root_prop.should_not be_nil
   @org_root_prop.trim.should_not be_empty
end

If either of those expectations fail then the examples that require
that property will report failures.  If I were using this all over the
place, I would write a custom matcher.

before(:each) do
  java.lang.System.should have_property("root")
  @org_root_prop = java.lang.System.getProperty("root")
end

This would allow you to define your own error message and perform more
sophisticated expectations (see the have_tag/with_tag example in
rspec-rails).

Note that you should be doing this check in before(:each) because you
want it to run before each example.  Also you should be using
before(:each) 99% of the time anyway.

Pat
Arthur S. (Guest)
on 2009-06-01 23:02
(Received via mailing list)
I thought the point was we don't want the examples to be run at all, if
the condition is not met? Though I'm wondering why not just handle
something like this with a stub (on System.getProperty in this case)?

       Arthur S.
Pat M. (Guest)
on 2009-06-01 23:56
(Received via mailing list)
Right, and in the code example I gave, if those preconditions fail
then the rest of the example won't be run.  There's not really any
need for a new semantic element in RSpec, it already works this way
out of the box.  You can do

it "should do something" do
  some_precondition.should be_met
  an_object.do_something
  some_postcondition.should be_met
end

If the precondition is not met, the example fails and halts right there.

If you do want to visually distinguish them for some reason, you can
do so easily:

def assumptions
  yield
end

it "should do something" do
  assumptions do
    some_precondition.should be_met
  end

  an_object.do_something
  some_postcondition.should be_met
end

I personally wouldn't :)  but you could.  I often use precondition
expectations in my examples.  It helps me know where an error is more
quickly.  I don't waste time tracking down errors that result from
some precondition (assumption) being incorrect.

Pat
mortench (Guest)
on 2009-06-02 00:03
(Received via mailing list)
On Jun 1, 8:04 pm, Arthur S. <removed_email_address@domain.invalid> wrote:
> I thought the point was we don't want the examples to be run at all, if
> the condition is not met?

Yes.

>Though I'm wondering why not just handle
> something like this with a stub (on System.getProperty in this case)?

Because the examples need the info in the property to work. The
property provides
reference values that the test use to compare against. Hence it makes
no sense to stub
anything out.

ALL: Thanks for all the help!

/Morten
Matt W. (Guest)
on 2009-06-02 00:59
(Received via mailing list)
On 1 Jun 2009, at 20:52, Pat M. wrote:

> You can do
>
> it "should do something" do
>  some_precondition.should be_met
>  an_object.do_something
>  some_postcondition.should be_met
> end

Also, more verbosely...

describe "when there is some precondition"
   before(:each) do
     do_stuff_which_attempts_to_set_up_some_precondition
     some_precondition.should be_met
   end

   it "should do something"
     an_object.do_something
     some_postcondition.should be_met
   end
end

Which, can often make your specs read nicely. I also offers an obvious
space to think of a few more examples to throw in there.

cheers,
Matt
This topic is locked and can not be replied to.