Mocking/Faking requests for js/ajax-based tests

Hello all,

I have an acceptance test that aims to bdd a Google Apps OpenID
authentication feature. This login screen also uses some JS (in order to
switch between the regular / Google OpenID forms). Now, I know this is
not
something that would prevent me from using the :rack driver for
Capybara,
but it made me think of the following problem: What to do when you have
a
JS/Ajax-oriented page that makes web service calls and you need to write
an
integration/acceptance test for it?

The fact that a scenario uses Javascript (Culerity/Selenium/Whatever)
means
it will need to spawn a different process (Not sure about EnvJS, but I
guess
it also needs a rails server running? ) for the rails app server. This
essentially prevents any mocking/stubbing/faking of requests. I wouldn’t
want a bunch of acceptance tests that actually make requests to web
services, certainly a testing no-no.

What do you guys think could be done in these cases? I remember seeing
something a long time ago (a lib) that actually tried to solve the
problem
of mocking while having the two processes open. Or maybe it’s too much
troube to write integration tests for these kind of features?

FYI, I’m using rSpec, Steak and Capybara+Culerity.

Marcelo.

One thing that just came to my mind is to fake the requests on the app
server instance. One simple way to do that would be to just put the
FakeWeb
call in a cucumber / culerity environment file. However, this is far
from
being elegant and is not scalable at all, as the call would be
contextless
to the spec that needs it.

Any other ideas?

Marcelo.

On Fri, Jun 18, 2010 at 11:46 AM, Marcelo de Moraes S. <

On Jun 18, 2010, at 12:02 PM, Marcelo de Moraes S. wrote:

One thing that just came to my mind is to fake the requests on the app server instance. One simple way to do that would be to just put the FakeWeb call in a cucumber / culerity environment file. However, this is far from being elegant and is not scalable at all, as the call would be contextless to the spec that needs it.

How about putting it in a step/step definition before the call gets
made?

Hi David, thanks for the reply,

Hmm, considering we have:

  1. The ruby process where the spec is running
  2. A mongrel server serving request (test environment)

If I call FakeWeb on #1, it won’t work on #2, since they are separated
processes and FakeWeb would only monkeypatch Net::HTTP for #1. Or am I
missing something?

Thanks!

Marcelo.

On Jun 18, 2010, at 5:02 PM, Marcelo de Moraes S. wrote:

Hi David, thanks for the reply,

Hmm, considering we have:

  1. The ruby process where the spec is running
  2. A mongrel server serving request (test environment)

If I call FakeWeb on #1, it won’t work on #2, since they are separated processes and FakeWeb would only monkeypatch Net::HTTP for #1. Or am I missing something?

No, I was missing something :slight_smile:

I’m not sure what the best way is here. On the apps I’m working on now,
we typically have all the ajax calls go back to the app and then make
requests to web services from the server. Makes it easier to test, log
failures, etc, etc.

Anybody else here testing client side web service calls?

What I typically do is wrap any Ajax calls on the client side with
JavaScript objects. Then it is fairly trivial to stub the calls by
just redefining the methods that would normally call the server.

For acceptance testing I would normally just do it end-to-end and not
mock. However, if there is some reason that you don’t want to call the
real thing (e.g. payment processor, authentication framework, etc.)
you could conditionally load the javascript that stubs the Ajax calls,
or you could implement a fake (i.e. a real simple implementation of
the web service that returns a canned response.)

On 19 Jun 2010, at 00:35, David C. wrote:

No, I was missing something :slight_smile:

I’m not sure what the best way is here. On the apps I’m working on now, we typically have all the ajax calls go back to the app and then make requests to web services from the server. Makes it easier to test, log failures, etc, etc.

Anybody else here testing client side web service calls?

David, I think you and the OP are still talking at cross-purposes.

Are you saying that when you use Capybara, the SUT runs in the same
process as the tests, even when you’re doing javascript/ajax tests?

On Jun 20, 2010, at 1:30 AM, Matt W. wrote:

Are you saying that when you use Capybara, the SUT runs in the same process as the tests, even when you’re doing javascript/ajax tests?
No. That’s what I meant by “No, I was missing something” - I had
forgotten about the separate processes when I responded earlier.