[LRUG] A question on DRYness on testing methods that get / set state
Tim Cowlishaw
tim at timcowlishaw.co.uk
Tue Nov 22 03:23:59 PST 2011
Hi there LRUG,
I've got a question about testing that's been bugging me for a while,
and I'd like to get your collective opinion on it, if that's ok. To
illustrate:
Let's say I have a class called 'Box' that exists solely to take a
value and store it in the box:
class Box
def put(item)
@item = item
end
def get
return item
end
end
Now, being a good, responsible developer, I decide to write specs for
my box (In fact, i probably even did this first if i was being
especially virtuous, but you get the idea):
describe Box do
describe "put" do
it "puts the item in the box" do
b = Box.new
b.put(:hello)
b.get.should == :hello
end
end
describe "get" do
"it gives me the item in the box" do
#oh shit! this is exactly the same as the spec for 'put'
b = Box.new
b.put(:hello)
b.get.should == :hello
end
end
end
So, my specs for get and put are identical, which, for a start isn't
very DRY, but also (and more importantly to my mind) is pretty
brittle. For instance, if a malicious person snuck into my codebase
and changed the implementation of 'get' to eg:
def get
return "I'm all up in your codebase, messing with your shit"
end
then the spec for 'get' would fail, as expected, but also the spec for
'put' would fail, even though there's nothing wrong with the
implementation of 'put' itself.
Of course, I could use instance_variable_get and instance_variable_set
to setup the object in the get spec, and inspect its state in the put
spec, but this ties my specs to that specific implementation of Box,
rather than simply the external interface / behaviour.
I guess this is a bit of a tradeoff, but I'd be curious to know - how
do you guys write tests for methods that get or set state? is there a
better way than the above?
Thanks,
Tim
More information about the Chat
mailing list