# TEST for REST!

**URL:** <https://www.ruby-forum.com/t/test-for-rest/128983>\
**Category:** Rails\
**Created:** [February 13, 2008, 8:54am UTC](https://www.ruby-forum.com/t/test-for-rest/128983 "2008-02-13T08:54:07Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![MohsinHijazee](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e68b1a/32.png) [@MohsinHijazee](https://www.ruby-forum.com/u/MohsinHijazee)\
**Post date:** [February 13, 2008, 8:54am UTC](https://www.ruby-forum.com/t/test-for-rest/128983/1 "2008-02-13T08:54:07Z")

</div>

Hello everyone!  
I’m writing tests for my REST API. Now the exposed resources  
regarding the REST are definately accessible through thier URLs like  
for the account resource, I’d do this:

# Trying to emulate GET /accounts.json

get ‘/accounts’, {:format =\> ‘JSON’}, {:user =\> User.find(1) }

But the above call fails and gives error that no action responds to ‘/  
accounts’. Even if I provide the fully qualified URL as ‘http://  
localhost:3000/accounts’ even then this fails.

Because the account is exposed as a resource in the config/routes.rb,  
we’ve a method accounts\_path or accounts\_url but both the methods are  
not accessible in the classes derived from Test::Unit::TestCase. What  
should I do in this regard?

Regards,  
Mohsin

---

<div class="post-metadata">

**Author:** ![MohsinHijazee](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e68b1a/32.png) [@MohsinHijazee](https://www.ruby-forum.com/u/MohsinHijazee)\
**Post date:** [February 13, 2008, 8:55am UTC](https://www.ruby-forum.com/t/test-for-rest/128983/2 "2008-02-13T08:55:53Z")

</div>

On 13 Feb 2008, at 07:53, MohsinHijazee wrote:

> accounts’. Even if I provide the fully qualified URL as ‘http://  
> localhost:3000/accounts’ even then this fails.
> 
> Because the account is exposed as a resource in the config/routes.rb,  
> we’ve a method accounts\_path or accounts\_url but both the methods are  
> not accessible in the classes derived from Test::Unit::TestCase. What  
> should I do in this regard?

Unit tests are not supposed to be testing at that level. You might  
want a functional test (but that doesn’t involve any sort of routing  
etc…) or integration tests

Fred

---

<div class="post-metadata">

**Author:** ![MohsinHijazee](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e68b1a/32.png) [@MohsinHijazee](https://www.ruby-forum.com/u/MohsinHijazee)\
**Post date:** [February 13, 2008, 9:11am UTC](https://www.ruby-forum.com/t/test-for-rest/128983/3 "2008-02-13T09:11:48Z")

</div>

On Feb 13, 12:55 pm, Frederick C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> > should I do in this regard?
> 
> Unit tests are not supposed to be testing at that level. You might  
> want a functional test (but that doesn’t involve any sort of routing  
> etc…) or integration tests  
> The functional tests are essentially also decedents of the  
> Test::Unit::TestCase as well just only being in a different directory  
> (that is, test/functional).  
> Integration testing is about the flow of control among the components.  
> I’ve placed my REST tests under the test/functional/restapi with the  
> following convention:  
> resourcename\_resource\_test.rb  
> So for the exposed resource accounts, I’ve the following test  
> test/functional/restapi/accounts\_resource\_test.rb

---

<div class="post-metadata">

**Author:** ![MohsinHijazee](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e68b1a/32.png) [@MohsinHijazee](https://www.ruby-forum.com/u/MohsinHijazee)\
**Post date:** [March 4, 2008, 12:36pm UTC](https://www.ruby-forum.com/t/test-for-rest/128983/4 "2008-03-04T12:36:05Z")

</div>

Would you be able to post an example of one of these restapi tests?  
How are you calling the API in the test and checking the result?

---

<div class="post-metadata">

**Author:** ![MohsinHijazee](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e68b1a/32.png) [@MohsinHijazee](https://www.ruby-forum.com/u/MohsinHijazee)\
**Post date:** [March 5, 2008, 8:45am UTC](https://www.ruby-forum.com/t/test-for-rest/128983/5 "2008-03-05T08:45:11Z")

</div>

On Mar 4, 4:35 pm, Olly L. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Would you be able to post an example of one of these restapi tests?  
> How are you calling the API in the test and checking the result?
> 
> On Feb 13, 8:11 am, MohsinHijazee [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > I’ve placed myRESTtests under the test/functional/restapi with the  
> > following convention:  
> > resourcename\_resource\_test.rb  
> > So for the exposed resource accounts, I’ve the following test  
> > test/functional/restapi/accounts\_resource\_test.rb

I’ve found a solution. Here is is:

Consider you want to test a rest api call like this one:

DELETE /users/1/posts/2/comments/3.json

this would basically invoke the CommentsController#destroy with  
following parameters available to this method through params hash:  
params[:user\_id]  
params[:post\_id]  
params[:id] #ID of the comment to be deleted.

So emulate this call in your tests, derive do this in your setup:

def setup  
@controller = CommentsController.new  
@request = ActionController::TestRequest.new  
@response = ActionController::TestResponse.new  
end

now write a test like this:

def test\_delete  
delete {:format =\> ‘json’, :user\_id =\> 1, :post\_id =\> 2, :id =\> 3},  
{} # Any session data you may want in the third hash

# And you are ready to roll!

assert\_response :succuss  
#More asserstions.  
end

Hope this explains how to write tests for the REST API of your  
application!

---

<div class="post-metadata">

**Author:** ![MohsinHijazee](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e68b1a/32.png) [@MohsinHijazee](https://www.ruby-forum.com/u/MohsinHijazee)\
**Post date:** [March 5, 2008, 8:49am UTC](https://www.ruby-forum.com/t/test-for-rest/128983/6 "2008-03-05T08:49:18Z")

</div>

I’ve found a solution. Here is is:

Consider you want to test a rest api call like this one:

DELETE /users/1/posts/2/comments/3.json

this would basically invoke the CommentsController#destroy with  
following parameters available to this method through params hash:  
params[:user\_id]  
params[:post\_id]  
params[:id] #ID of the comment to be deleted.

So emulate this call in your tests, do this in your setup:

def setup  
@controller = CommentsController.new  
@request = ActionController::TestRequest.new  
@response = ActionController::TestResponse.new  
end

now write a test like this:

def test\_delete  
delete :destroy, {:format =\> ‘json’, :user\_id =\> 1, :post\_id =\>  
2, :id =\> 3},  
{} # Any session data you may want in the third hash

# And you are ready to roll!

assert\_response :succuss  
#More asserstions.  
end

Hope this explains how to write tests for the REST API of your  
application!

---

<div class="post-metadata">

**Author:** ![MohsinHijazee](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e68b1a/32.png) [@MohsinHijazee](https://www.ruby-forum.com/u/MohsinHijazee)\
**Post date:** [March 5, 2008, 8:42pm UTC](https://www.ruby-forum.com/t/test-for-rest/128983/7 "2008-03-05T20:42:41Z")

</div>

While that tests the controller, I like to test the REST API the same  
way my client code would use it by sending XML (or JSON, if you like)  
to the URL using an integration test.

class RestXmlTest \< ActionController::IntegrationTest

def test\_create\_order  
post “/orders.xml”,  
“Michael”,  
{:content\_type =\> “application/xml”}  
assert\_response 201

end  
end

Clearly, there are all kinds of assertions you can make after this,  
but this gets you rolling at this level.

---

<div class="post-metadata">

**Author:** ![MohsinHijazee](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e68b1a/32.png) [@MohsinHijazee](https://www.ruby-forum.com/u/MohsinHijazee)\
**Post date:** [March 6, 2008, 11:12am UTC](https://www.ruby-forum.com/t/test-for-rest/128983/8 "2008-03-06T11:12:45Z")

</div>

I’ve answered my own question:

get “/action.xml”, :content\_type =\> “application/xml”, :authorization  
=\>  
ActionController::HttpAuthentication::Basic.encode\_credentials(‘user’,  
‘password’)

Cheers, Olly

---

<div class="post-metadata">

**Author:** ![MohsinHijazee](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e68b1a/32.png) [@MohsinHijazee](https://www.ruby-forum.com/u/MohsinHijazee)\
**Post date:** [March 6, 2008, 12:23am UTC](https://www.ruby-forum.com/t/test-for-rest/128983/9 "2008-03-06T00:23:17Z")

</div>

Thanks for this.

My controllers require HTTP Basic authentication. What would be the  
best way to add support for this to the integration test below?
