It’s interesting that this thread has started because I just ran into
this problem.
The error I got was:
NoMethodError in ‘Signup she be a valid mac address’
protected method `normalize_mac’ called for #Signup:0x408c0434
./spec/models/signup_spec.rb:10:
Here’s the spec:
describe Signup do
before(:each) do
@signup = Signup.new
end
it “she be a valid mac address” do
@signup.mac_address = “00-11-22-33-44-55-66”
normalized = @signup.normalize_mac(@signup.mac_address)
@signup.mac_address.should == normalized
end
end
I have a model that has mac_address attribute. In the before
validation, I wanted to make the mac address have colons( instead of
whatever the user typed in which could have spaces between, dashes,
nothing at all.
My thought was to just remove all of those special characters validate
it against a regex then if it passed the regex check produce the mac
address with the colons included.
And, if I understand it properly, Pat’s statement is saying that I
really shouldn’t be protecting that method…which would fix my problem.
So my question is then, how do you know when to use protected and
private or do I just do what Rick suggested and use send?
I just realized this isn’t really an rspec question…so I’ll just move
along.
Mike B.
Apart from private or public methods I see a problem in your test case.
You don’t make sure that your mac_address is returned in exactly the way
you want - you are merely saying it should look like the return value of
some (protected) method you call (normalize_mac).
Let’s assume this method was implemented wrong and just returns nil.
Let’s further assume that @signup.mac_address calls a reader method
returning nil, too. Such an implementation, though wrong, would satisfy
your spec!
A second problem is, that the parameter you are passing to the
normalize-method will already have been transformed before your method
gets its hands on it. You are not passing the init value but the value
that is returned be a read operation on the mac_address field.
What you really should specify is your concrete mac address format:
it "should return a valid mac address" do
@signup.mac_address = "00-11-22-33-44-55"
@signup.mac_address.should == "00:11:22:33:44:55"
end
Now you are not only implementation independent but your spec is also
saying more.
François
barsalou schrieb:
On 10.1.2008, at 22.21, Francois W. wrote:
returning nil, too. Such an implementation, though wrong, would
it “should return a valid mac address” do
@signup.mac_address = “00-11-22-33-44-55”
@signup.mac_address.should == “00:11:22:33:44:55”
end
Now you are not only implementation independent but your spec is also
saying more.
Also, this line of code is a bit smelly:
normalized = @signup.normalize_mac(@signup.mac_address)
Since normalize_mac is an instance method in the Signup class, there’s
no point passing the mac_address as a parameter; the method can simply
call the mac_address method directly. If you want to make it more
general-purpose, it doesn’t sound like it should be an instance method
anymore.
//jarkko
–
Jarkko L.
http://www.railsecommerce.com
http://odesign.fi
On Jan 10, 2008 12:25 PM, Jarkko L. [email protected] wrote:
Also, this line of code is a bit smelly:
normalized = @signup.normalize_mac(@signup.mac_address)
Since normalize_mac is an instance method in the Signup class, there’s
no point passing the mac_address as a parameter; the method can simply
call the mac_address method directly. If you want to make it more
general-purpose, it doesn’t sound like it should be an instance method
anymore.
Right, you could pull this into a MacAddress class, and use that:
describe MacAddress, " for 00-11-22-33-44-55" do
it “should normalize to 00:11:22:33:44:55” do
MacAddress.new(“00-11-22-33-44-55”).to_s.should ==
“00:11:22:33:44:55”
end
end
Then you can just do
@signup.mac_address = MacAddress.new “00-11-22-33-44-55”
and you don’t really need to test that, of course, since it’s just a
setter.
Pat
Even my suggestion wouldn’t be a sufficient spec. What about completely
wrong mac addresses? Empty addresses, too many characters, invalid
characters?
It is not for nothing that the rspec test cases are called examples -
you may define any number of example inputs and expected outputs that
are required to describe the behavior of the object to be specified.
barsalou schrieb:
On Jan 10, 2008 12:34 PM, Francois W. [email protected]
wrote:
Even my suggestion wouldn’t be a sufficient spec. What about completely
wrong mac addresses? Empty addresses, too many characters, invalid
characters?
I just sent a reply that crossed wires with yours…anyway,
introducing a MacAddress class here would be great for solving these
sorts of problems. Mac address validation is something that the
@signup object should not be concerned with.
Pat
Yes, you’re absolutely right. I somehow ignored the class name in my
previous answers, but that would have been the next point of attack.
Pat M. schrieb: