On Fri, 12 Dec 2003 08:55:43 +1300
Nick Phillips <[EMAIL PROTECTED]> wrote:

> So far as I can see, that is all directed at testing by sending a 
> request
> to a server and checking what comes back; that's really not useful for
> testing components of code individually, which is the point. I don't
> want to test the server, I want to individually test each chunk of my 
> code.

If you want to test your component individually, what you'd better
do first is to split your methods into easy-to-test form, and then
use MockObject methods to unittest it. 

I mean, if your individual business logical methods depend on
Apache::* modules internally, that's a bad design, from the
viewpoint of unit testing.

Let's consider for example, testing an application that
concatinates Cookie's foo value and query parameter bar: 

  sub run {
      my $self = shift;

      my $cookie = Apache::Cookie->fetch();
      my $apr    = Apache::Request->instance();

      my $val = $cookie{foo}->value . $apr->param('bar');
      $apr->send_http_header();
      $apr->print($val);

      return OK;
  }

This is not something unit test friendly, as it calls Apache::*
modules inside the method. You can split this methods into
module-indepent forms like this:

  # untested code, but you can get the feeling

  sub run {
      my $self = shift;
      my $val = $self->get_cookie('foo') . $self->request_param('bar');
      $self->output_content($val);
  }

  sub get_cookie {
      my($self, $key) = @_;
      $self->{cookie}->{$key} ||= Apache::Cookie->fetch($key);
  }
 
  sub request_param {
      my($self, $key) = @_;
      # you should set Apache::Request object into r
      return $self->{r}->param($key);
  }

  sub output_content [
      my($self, $value) = @_;
      $self->{r}->send_http_header();
      $self->{r}->print($value);
  }
  
Then, when you test your run() method, you can change yoru
variable by mocking up yoru own methods or store MockObject into
necessary parts.

  my $app = Your::App->new();

  local *Your::App::get_cookie    = sub { return "foooo" };
  local *Your::App::request_param = sub { return "barrr" };

  my $out;
  local *Your::App::output_context = sub { $out = $_[1] };

  # run it
  $app->run();

  # output is stored to $out
  is $out, "foooobarrr";



--
Tatsuhiko Miyagawa
[EMAIL PROTECTED]


-- 
Reporting bugs: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html

Reply via email to