What I’d like to do is create a shared_examples group which I can
parametize
a method. So my shared example would perhaps use method named_address=,
or
set_named_address and then groups that behave like “Named address” would
be
able to override this method so it sets the correct address e.g. the
last
billing address
able to override this method so it sets the correct address e.g.
the last
billing address
Here’s the short version: There’s been a lot of discussion on this
list about parameterizing shared examples. Basically, given the
current design it can’t happen, and macros are a perfectly good
solution to the problem, so there’s not much incentive to change the
design.
You can use instance variables to pass values to the shared examples,
though, right?
Please have a look at 131277’s gists · GitHub
What I’d like to do is create a shared_examples group which I can parametize
a method. So my shared example would perhaps use method named_address=, or
set_named_address and then groups that behave like “Named address” would be
able to override this method so it sets the correct address e.g. the last
billing address
Here’s the short version: There’s been a lot of discussion on this
list about parameterizing shared examples. Basically, given the
current design it can’t happen, and macros are a perfectly good
solution to the problem, so there’s not much incentive to change the
design.
I’ll try to follow up later with a recommendation about a macro,
unless somebody else beats me to it
What I’d like to do is create a shared_examples group which I can
current design it can’t happen, and macros are a perfectly good
solution to the problem, so there’s not much incentive to change the
design.
You can use instance variables to pass values to the shared examples,
though, right?
At your own risk, yes, of course
If you do go down that route, I recommend method calls instead of
instance variables. That way it will yell out you when you forget to
define one.
What I’d like to do is create a shared_examples group which I can parametize
a method. So my shared example would perhaps use method named_address=, or
set_named_address and then groups that behave like “Named address” would be
able to override this method so it sets the correct address e.g. the last
billing address
This is horrendously ugly, but I was able to achieve something like
what you’re talking about using a combination of instance variables
and ‘eval’ statements in the shared behavior. See:
Readable and elegant? Not really. But I have to set up a crapload of
these classes layered on top of somebody else’s SOAP API, and spec
completeness was more important to me than spec maintainability.
Here’s the short version: There’s been a lot of discussion on this
list about parameterizing shared examples. Basically, given the
current design it can’t happen, and macros are a perfectly good
solution to the problem, so there’s not much incentive to change the
design.
I’ll try to follow up later with a recommendation about a macro,
unless somebody else beats me to it
I beat David to it. Here are some options:
I think I like #7 and #8 the best with the eval and #subject use. With #8 I intentionally modify the backtrace so that the when errors happen
it points to where the macro was called, not defined. Sometimes this is
desirable, YMMV. FWIW, I question the value of such specs… but that
is the macro approach.
a method. So my shared example would perhaps use method named_address=,
current design it can’t happen, and macros are a perfectly good macro example and variations · GitHub
I think I like #7 and #8 the best with the eval and #subject use. With #8
I intentionally modify the backtrace so that the when errors happen it
points to where the macro was called, not defined. Sometimes this is
desirable, YMMV. FWIW, I question the value of such specs… but that is
the macro approach.
-Ben
Wow thankyou for that what a spectacular response!
I’ve spent much of my afternoon digesting your suggestions, learning
lots of
new stuff (and added lots to my 'things I really should know" list).
I’ve
managed to get well on the way to solving my problems and hopefully will
end
up with a compact and elegant solution both in code and specs.
So once again thankyou Ben, and thankyou rspec-mailing list
If you do go down that route, I recommend method calls instead of instance
variables. That way it will yell out you when you forget to define one.
Hey, instance variables do that too. Yelling == “my tests fail.” >8->
(And if they don’t, I’m really doing something wrong…)
But methods are more explicit. Suppose you want to parametrize on the
value of a certain property named “bar”. Not defining @bar will raise
an NoMethodError because you called something on nil. Not defining the
method will raise a NoMethodError because bar isn’t defined, which
tells you immediately what you need to solve.
You could also do something like
def bar
raise NotImplementedError, “please define this method in each of
your example groups that use this shared behavior”
end
and it will be even more explicit. But this means you have to define
the method after you include the shared examples, or it will fail
(which is a code smell, IMO).
-foca
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.