[mocha-developer] Need some help in reducing my repetions in tests with Mocha

Jay Fields jay at jayfields.com
Sat May 3 08:49:00 EDT 2008

Hi Jon,

It's hard to give good advice because we are missing too many pieces  
of information. For example, your test references both @base and  
"good_response", neither of which are shown elsewhere. Also, without  
your domain code it's hard to say what the best way to test it is.

But, not having enough information has never stopped me from giving my  
opinion before...

I looks to me like you should create smaller methods, if not a few  
more classes depending on how much is going on. For example, you want  
to test that the token is in the parameters, so why not create a  
method that returns the url. If you have a method that returns the  
url, then you can test that method in isolation.

On my last project I used Net::HTTP, and I understand it can be a bit  
of a tangled web, but I created a Gateway class that hid all the  
complexity of Net::HTTP from my domain. The Gateway class also had  
many small methods that I could test in isolation or as part of larger  
tests. The small methods are helpful in the larger tests because you  
can stub the methods you don't care about.

Cheers, Jay

On May 3, 2008, at 1:08 PM, Jonathan Stott wrote:

> Hi All
> I'm writing a gem to interact with the todoist JSON API and I'm  
> using mocha to mock the server responses so I don't have to have a  
> net connection to test and so I don't need to actually use my own  
> API key anywhere.
> Mostly I am interested in verifying that a correctly formatted URL  
> has been sent, with the appropriate parameters, e.g API key have  
> been sent. So I end up with expectations like so:
> it "includes a token in the parameters" do
>  http = mock()
>  http.stubs(:use_ssl=)
>  http.expects(:get).with { |url|
>    url.split("?",2).last =~ /token=#{@token}/
>  }.returns(good_response)
>  Net::HTTP.stubs(:new).returns(http)
>  @base.query("viewall")
> end
> But the problem is, all my expectations basically feature the same  
> lines of code (from http = mock() to Net::HTTP stubs) with only the  
> "with" block changing.  But because it is the with block changing,  
> I'm not sure how to create a method which will insert my changing  
> block into the middle of the expectation call.
> Well, I have a prototype method:
> def web_stub(good=true,&block)
>  http = mock()
>  http.stubs(:use_ssl=)
>  get = http.expects(:get)
>  if block_given?
>    get = yield get
>  end
>  get.returns(good ? good_response : bad_response)
>  Net::HTTP.stubs(:new).returns(http)
> end
> But this requires me to use the very ugly syntax of
> web_stub do |get|
>  get.with do |url|
>    url.split("?",2).first =~ /query$/
>  end
> end
> And I'd like to avoid the need for nested blocks if possible.
> Any pointers on how to implement the method, or a better way of  
> doing it in general would be appreciated!
> Regards,
> Jon
> _______________________________________________
> mocha-developer mailing list
> mocha-developer at rubyforge.org
> http://rubyforge.org/mailman/listinfo/mocha-developer

More information about the mocha-developer mailing list