@TheKeyboard

Testing Components in CakePHP

| Comments

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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
require_once LIBS . '/controller/components/email.php';

class EmailTestController extends Controller {
  var $name = 'EmailTest';
  var $uses = null;
  var $components = array('Email');
}

class EmailTest extends CakeTestCase {
  var $name = 'Email';

  function setUp() {
      $this->Controller =& new EmailTestController();

      restore_error_handler();
      @$this->Controller->_initComponents();
      set_error_handler('simpleTestErrorHandler');

      $this->Controller->Email->startup($this->Controller);
      ClassRegistry::addObject('view', new View($this->Controller));
  }

  function testSmtpSend() {
      $this->Controller->Email->to = 'chartjes@localhost';
      $this->Controller->Email->subject = 'Cake SMTP test';
      $this->Controller->Email->replyTo = 'noreply@example.com';
      $this->Controller->Email->from = 'noreply@example.com';
      $this->Controller->Email->delivery = 'smtp';
      $this->Controller->Email->template = null;
      $this->assertTrue($this->Controller->Email->send("This is the body of the message"));
  }

}
?>

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.