Test Driven Design and Rails Helpers

I have a bit of a problem trying to implement using TDD. As I understand it the idea is to decide what you want the code to do, write a test to check that it does, then write the code and get it to pass the test.

I keep coming across a problem with this, here is an example:

What I want the code to do:
Show a link_to_remote on the page, referencing a particular url with params and a particular div.

I am using the built in rails test system. As far as I can see the only way to check my link_to_remote is coded correctly is by using assert_select to check the html in the response. This is easy enough to do but requires knowledge of the html that link_to_remote generates. So what I have to do is write the view first, containing the link to remote, check that the link works correctly, look at the html and write the test.

Is there an alternative? Apologies if this has been discussed at length elsewhere, I googled in vain.

Colin

Colin Law wrote:

I have a bit of a problem trying to implement using TDD. As I

understand it

the idea is to decide what you want the code to do, write a test to

check

that it does, then write the code and get it to pass the test.

I keep coming across a problem with this, here is an example:

What I want the code to do:

Show a link_to_remote on the page, referencing a particular url with

params

and a particular div.

I am using the built in rails test system. As far as I can see the only

way

to check my link_to_remote is coded correctly is by using assert_select

to

check the html in the response. This is easy enough to do but requires

knowledge of the html that link_to_remote generates. So what I have to

do

is write the view first, containing the link to remote, check that the

link

works correctly, look at the html and write the test.

Is there an alternative? Apologies if this has been discussed at length

elsewhere, I googled in vain.

Hey,

maybe if you start differently it will be easier:

  1. First write a test for the action. (What should it do)

  2. Then implement the action.

  3. Then write a test for the link_remote_to placement within whichever

template/action-render

  1. Then change the template to contain the link.

At point 3 you should know the form of the URL that is required.

I think I have not explained myself adequately. I have no problem with points 1 and 2 - the test and the implementation for the action invoked when the remote call is made. It is point 3 that is the problem. How do I write the test for the link_to_remote placement unless I know the form of the html that link_to_remote generates? I know the URL but not how the div and url appear within the Ajax.Updater javascript call. In principle I do not even know that there is an Ajax.Updater call, nor whether I need to check any of the other parameters of the call.

The same problem appears with helpers such as datetime_select, until I put it on the page and look at how the individual select boxes are configured, how can I write the test to check that it has been initialised with the correct data?

Colin

Colin Law wrote:

I think I have not explained myself adequately. I have no problem with points 1 and 2 - the test and the implementation for the action invoked when the remote call is made. It is point 3 that is the problem. How do I write the test for the link_to_remote placement unless I know the form of the html that link_to_remote generates?

Here is a bit of hemming and hawing, while I work on projects other than assert_xhtml and assert_rjs_ (as seen at http://c2.com/cgi/wiki?AssertXhtml )

TDD (aka BDD) works best on greenfield projects - ideally on platforms which were themselves invented via TDD. Such projects will have assertions matching each feature, ready to use. You simply alternate between writing assertions and writing code statements.

> I know the URL but not

how the div and url appear within the Ajax.Updater javascript call. In principle I do not even know that there is an Ajax.Updater call, nor whether I need to check any of the other parameters of the call.

When TDDing into a legacy system, especially a View, expect to cheat early and often.

Write the test up until the point where you have no assertion, then fudge it. Assert that your <a onclick> matches 42, for example.

Write the code you want, get the assertion to fail, and look at the diagnostic. Copy its relevant details into your assert_match, and keep going. A change in the RJS library might someday break your assertion; you don't care.

The _next_ time you TDD an <a onclick>, clone that assertion and upgrade it. You will soon discover an application-specific assertion pattern which might work for all Ajax in the world, but will tolerably propel your own project.

My assert_rjs_ is teetering on the brink of doing this:

   a = assert_xhtml{|x| x.a.my_id! }
   assert_rjs_ a[:onclick], :remote_function, :url => { :action => 'yo' }

However, these days I am shamelessly earning money instead of working on it. Sorry! (-:

OK, thanks, that is pretty much what I have been doing. I thought there might be a better way.
Colin