I have done BDD in C# and my question is that how Spec in IronRuby makes
it easier. Here is what my test looks like:
require ''rubygems''
require ''spec''
require File.dirname(__FILE__) +
''/bin/Debug/BusinessObjects.dll''
include BusinessObjects
primeService = PrimeService.new
describe PrimeService,"when 1 is passed" do
it "should return true" do
primeService.IsPrime(1).should == true
end
end
describe PrimeService, "when 2 is passed" do
it "should return true" do
primeService.IsPrime(2).should == true
end
end
describe PrimeService, "when a number less then zero is passed" do
it "should throw an error for invalid input exception" do
lambda {primeService.IsPrime(-1)}.should raise_error
end
end
describe PrimeService, "when a prime number is passed" do
it "should return a true value" do
prime_numbers = [3,23,5,7,11,13,19,17,29]
prime_numbers.each{|x| primeService.IsPrime(x).should == true}
end
end
Is this the normal way of writing unit test BDD style using Spec and
IronRuby or am I missing something?
--
Posted via http://www.ruby-forum.com/.
I would write it as follows:
###FILE spec_helper.rb####
require ''rubygems''
require ''spec''
def be_prime_for(expected)
simple_matcher("a prime number") {|given| given.is_prime(expected)}
end
####spec file###
require ''path/to/spec_helper''
require File.dirname(__FILE__) +
''/bin/Debug/BusinessObjects.dll''
include BusinessObjects
describe PrimeService do
before(:each) do
@prime_service = PrimeService.new
end
it "should be prime for 1" do
@prime_service.should be_prime_for 1
end
it "should be prime for 2" do
@prime_service.should be_prime_for 2
end
it "should raise an error for invalid input" do
lambda {@prime_service.is_prime(-1)}.should raise_error
end
it "should be ''true'' for prime numbers" do
[3,23,5,7,11,13,19].each {|x| @prime_service.should be_prime_for x}
end
it "should be ''false'' for non-prime numbers" do
[4,6,9,12,21].each {|x| @prime_service.should_not be_prime_for x}
end
end
Notable points:
a) 2 files, you can add more matchers and other common setup to spec_helper.rb
and require it in other spec files.
b) use before(:each) for test setup. It ensures isolation
c) no need for multiple contexts in this case.
d) custom matchers increase the readability
Hope that helps.
JD
...there is no try
> -----Original Message-----
> From: ironruby-core-bounces at rubyforge.org [mailto:ironruby-core-
> bounces at rubyforge.org] On Behalf Of Mohammad Azam
> Sent: Monday, July 06, 2009 7:11 PM
> To: ironruby-core at rubyforge.org
> Subject: [Ironruby-core] RSpec Test Format
>
> I have done BDD in C# and my question is that how Spec in IronRuby makes it
> easier. Here is what my test looks like:
>
> require ''rubygems''
> require ''spec''
>
> require File.dirname(__FILE__) +
''/bin/Debug/BusinessObjects.dll''
>
> include BusinessObjects
>
> primeService = PrimeService.new
>
> describe PrimeService,"when 1 is passed" do
>
> it "should return true" do
>
> primeService.IsPrime(1).should == true
>
> end
>
> end
>
> describe PrimeService, "when 2 is passed" do
>
> it "should return true" do
>
> primeService.IsPrime(2).should == true
>
> end
>
> end
>
> describe PrimeService, "when a number less then zero is passed"
do
>
> it "should throw an error for invalid input exception" do
>
> lambda {primeService.IsPrime(-1)}.should raise_error
>
> end
>
> end
>
> describe PrimeService, "when a prime number is passed" do
>
> it "should return a true value" do
>
> prime_numbers = [3,23,5,7,11,13,19,17,29]
>
> prime_numbers.each{|x| primeService.IsPrime(x).should == true}
>
> end
>
> end
>
>
> Is this the normal way of writing unit test BDD style using Spec and
IronRuby
> or am I missing something?
> --
> Posted via http://www.ruby-forum.com/.
> _______________________________________________
> Ironruby-core mailing list
> Ironruby-core at rubyforge.org
> http://rubyforge.org/mailman/listinfo/ironruby-core
Mohammad Azam wrote:> I have done BDD in C# and my question is that how Spec in IronRuby makes > it easier. Here is what my test looks like:> <snip test code....>> Is this the normal way of writing unit test BDD style using Spec and > IronRuby or am I missing something?I''m definitely no BDD expert, but I''ll try to take a stab at it. Apologies if I put my foot in my mouth. People actually using BDD full-time, please chime in and/or shoot me down. Personally, I believe that some of this is just aesthetics, and some of it is actually aiming to make you think about making your libraries'' intent as clear as possible. I think you can refactor as you go, and when the specifications read close to natural language, you''ve gotten somewhere. Re: Your specific question about what RSpec brings that C# can''t achieve.. I think it''s the same as most ruby vs. C# issues, ruby gets out of our way, where C# simply isn''t able to. I''d say the closest you get (arguably) in C# is MSpec: http://codebetter.com/blogs/aaron.jensen/archive/2008/05/08/introducing-machine-specifications-or-mspec-for-short.aspx http://github.com/machine/machine.specifications/tree/master Where you have to work around what the C# compiler needs, you have to write things like: Because of = () => fromAccount.Transfer(1m, toAccount); Check here for a simple MSpec example: http://github.com/machine/machine.specifications/blob/0db4d72c93fdc4f5775d9b1eb6239b64a76ad562/Source/Machine.Specifications.Example/BankingSpecs.cs I''m not trying to knock MSpec at all, but if you look at what you''ve written above to achieve the same context/specification style, I think you might agree ruby does a better job getting out of your way to let you do what you intend. The C# compiler needs a lot more to be happy, so MSpec does its very best to get around that. There is a lot of good material around RSpec and Cucumber, and the art of writing specifications for it as well. -- Posted via http://www.ruby-forum.com/.
Thanks Kevin for the detailed answer. I agree that Spec makes easier to
perform BDD style testing. Although I have never used MSpec for C#. I
usually write my C# BDD style test manually without any tools. Like the
following:
public class when_1_is_passed_to_the_prime_service
{
public void should_make_sure_true_is_returned()
{
}
}
Thanks for the input!
--
Posted via http://www.ruby-forum.com/.