Mocking Net::HTTP

I am currently finishing up a release of Rannel, a library for
sending sms messages through the open source SMS/WAP Gateway Kannel.

I have a couple of Unit tests that assure that the commands are send
correctly to Kannel and all the tests are passing (i.e. it’s
working :slight_smile: ).

Looking at the unit test code though, I realized, that I am violating
one of the unit test premisses; The Independence of the Tests!

Therefore I thought that I could mock up the Net::HTTP requests done
to Kannel, but my problem here is that I am not quite sure how I can
do that, as the adapters (for GET and POST requests) actually use
this package (Net::HTTP).

What would you recommend? Should I write a MockGet/Post adapter that
will do the job? Or is there a transparent way to change the behavior
of Net::HTTP without touching the adapters?

Thank you in advance,

Enrique Comba R.

On Sat, May 26, 2007 at 01:45:06AM +0900, Enrique Comba R.
wrote:

Therefore I thought that I could mock up the Net::HTTP requests done
to Kannel, but my problem here is that I am not quite sure how I can
do that, as the adapters (for GET and POST requests) actually use
this package (Net::HTTP).

What would you recommend? Should I write a MockGet/Post adapter that
will do the job? Or is there a transparent way to change the behavior
of Net::HTTP without touching the adapters?

I’m pretty sure Flexmock can do this.
http://onestepback.org/software/flexmock/

Scan down to “Mocking Class Objects”. I’ve used it to mock calls to my
own
classes (but not Net::HTTP)

On 25/05/07, Enrique Comba R. [email protected] wrote:

What would you recommend? Should I write a MockGet/Post adapter that
will do the job? Or is there a transparent way to change the behavior
of Net::HTTP without touching the adapters?

You should be able to use Mocha (http://mocha.rubyforge.org) do do this.

Let me know if you have a specific test you need help with.

On 25 May 2007, at 20:09, James M. wrote:

James.
http://blog.floehopper.org

Hi James, Brian!

I’ve taken a look at both frameworks and the following question
arises. If I am using my classes like the way I am using, how can I
possibly mockup Net::HTTP?

Let me try to explain with a sample testing code (taken from one of
the unit tests):

def test_send_through_get_adapter
Rannel::Base.establish_connection(@adapters[“get”]) # The
configuration comes from Yaml

sms = Rannel::Base.create_sms
sms.from = "123124"
sms.to = 2356556652
sms.text = "Hello"

assert_equal(@OK, Rannel::Base.deliver(sms))

end

The problem here is that the deliver(sms) call actually calls the
adapter to deliver the SMS. In the case of the GetRequestAdapter (the
one that makes the GET request) this looks like this:

def deliver(sms)
result = “”
Net::HTTP.start(@ip, @port) do |http|
url = “/cgi-bin/sendsms?username=#{@user}” +
“&password=#{@password}#{sms.to_kannel}”
response = http.get(url)
result = response.body
end
result
end

So how can I then, from the Unit Test mockup the call that is being
made to Net::HTTP?

Thanks a lot for the help!


Enrique Comba R.
[email protected]

I always thought Smalltalk would beat Java, I just didn’t know it
would be called ‘Ruby’ when it did.
– Kent Beck

You should be able to do something like this…

http://pastie.caboo.se/64679

Note that this is all stubs. If you want to assert that a particular
method is called you need to use Mock#expects instead of Mock#stubs.
If you want to assert that the method is called with particular
parameters, you can use the Expectation#with.

Also you might be able to use more real objects e.g. the response
object…?

I hope this makes sense. Probably best to come over to the Mocha list
if you want more help…

http://rubyforge.org/mailman/listinfo/mocha-developer

No problem :slight_smile:

On 25 May 2007, at 23:40, James M. wrote:

object…?

I hope this makes sense. Probably best to come over to the Mocha list
if you want more help…

http://rubyforge.org/mailman/listinfo/mocha-developer

James.
http://blog.floehopper.org

I checked your code and made a change in my test code taking that
pastie (well the mock part of it) and commented out all the other
tests… Run the tests and looked at the logs from kannel to see if
there is any request hitting kannel…

And guess what?

Hey it works! :slight_smile: :slight_smile: :slight_smile:

Thanks a million!

Enrique

On May 26, 6:46 am, Brian C. [email protected] wrote:

On Sat, May 26, 2007 at 04:25:59AM +0900, Enrique Comba R. wrote:

I’ve taken a look at both frameworks and the following question
arises. If I am using my classes like the way I am using, how can I
possibly mockup Net::HTTP?

By overriding Net::HTTP’s “new” method to return a new mock object which has
whatever behaviour you like. Or if you’re using Net::HTTP.start, then
override that.

I need to develop a mockup server, so i can do performance testing
without needing the real server. I am only testing the client or the
Rails application so i do not need to use real server.

I need to override couple of Net::HTTP methods. Can you suggest which
framework is better to start with to create mockup objects which would
respond to the requests.

Thanks in advance

On Sat, May 26, 2007 at 04:25:59AM +0900, Enrique Comba R.
wrote:

I’ve taken a look at both frameworks and the following question
arises. If I am using my classes like the way I am using, how can I
possibly mockup Net::HTTP?

By overriding Net::HTTP’s “new” method to return a new mock object which
has
whatever behaviour you like. Or if you’re using Net::HTTP.start, then
override that.