Testing Components In CakePHP

Since I was moaning to Larry about the lack of tests in CakePHP (even though there is a great test suite based on Simpletest) I felt obliged to add in some tests to my work on adding functionality to the Email component to allow it to send things via SMTP.

Using the test suite is actually quite easy: drop SimpleTest into your cake/vendors directly and you're ready to start writing your tests. Having written tests using SimpleTest before it wasn't going to be too hard for me to get them done. But there was one little problem: how do you test a component?

Components are called via controllers, so there was no way for me to simply instantiate the component and test it out. After much back-and-forth with Larry (aka PhpNut) via IM I got it working.

PHP:
  1. require_once LIBS . '/controller/components/email.php';
  2.  
  3. class EmailTestController extends Controller {
  4.     var $name = 'EmailTest';
  5.     var $uses = null;
  6.     var $components = array('Email');
  7. }
  8.  
  9. class EmailTest extends CakeTestCase {
  10.     var $name = 'Email';
  11.  
  12.     function setUp() {
  13.         $this->Controller =& new EmailTestController();
  14.  
  15.         restore_error_handler();
  16.         @$this->Controller->_initComponents();
  17.         set_error_handler('simpleTestErrorHandler');
  18.  
  19.         $this->Controller->Email->startup($this->Controller);
  20.         ClassRegistry::addObject('view', new View($this->Controller));
  21.     }
  22.  
  23.     function testSmtpSend() {
  24.         $this->Controller->Email->to = 'chartjes@localhost';
  25.         $this->Controller->Email->subject = 'Cake SMTP test';
  26.         $this->Controller->Email->replyTo = 'noreply@example.com';
  27.         $this->Controller->Email->from = 'noreply@example.com';
  28.         $this->Controller->Email->delivery = 'smtp';
  29.         $this->Controller->Email->template = null;
  30.         $this->assertTrue($this->Controller->Email->send("This is the body of the message"));
  31.     }
  32.  
  33. }
  34. ?>

The trick ended up being me not knowing to create an instantiation of the controller and then telling it to initialize all components. Before I was doig that I woudl get all sorts of controller-related errors. The internals of CakePHP are slowly being revealed to me, which is a good thing because working for CDC pretty much guarantees I will need to understand them inside and out.

I know that testing isn't very glamourous but can you imagine how to debug an Email compnent that sends out email on a specific TCP port without a repeatable unit test? Me neither.

5 Responses to this post.

  1. Daniel Hofstetter's Gravatar

    Posted by Daniel Hofstetter on 26.06.07 at 4:50 pm

    Your test fails here:

    1) at [/home/dho/projects/cake_1.2.x.x/cake/tests/cases/libs/controller/components/email.test.php line 58]
    in testSmtpSend
    in EmailTest
    in /home/dho/projects/cake_1.2.x.x/cake/tests/cases/libs/controller/components/email.test.php
    FAILURES!!!
    Test cases run: 23/23, Passes: 2135, Failures: 1, Exceptions: 0

  2. Chris Hartjes's Gravatar

    Posted by Chris Hartjes on 26.06.07 at 4:50 pm

    @Daniel: Yeah, there was some weirdness going on with my local mail server on my development box, so I have to figure this stuff out today...it fails at unpredictable parts of the communication with an SMTP server so reproducing it is hard.

  3. developercast.com » Chris Hartjes’ Blog: Testing Components In CakePHP's Gravatar

    [...] Hartjes has posted a quick example of a useful method for CakePHP developers - how to test components. Using the test suite is [...]

  4. E's Gravatar

    Posted by E on 26.06.07 at 4:50 pm

    Archives link at top is broken
    http://www.littlehart.net/atthekeyboard

  5. Chris Hartjes's Gravatar

    Posted by Chris Hartjes on 26.06.07 at 4:50 pm

    @E - thanks for pointing that

Respond to this post

Want to advertise on this blog? Send email to chartjes@littlehart.net
GTcars Canadian Car Audio TurboDodge Audi Forum
Mustang Forum Dodge Intrepid Miata Turbo
GTscene Pontiac Bonneville