Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHPUnit tests real example

I've created a mail wrapper class. I know that there are lots of libraries to send e-mails but i want to learn TDD... So, I've created some tests and i have some code. Now I can set the email address on constructor and validate it... if the email address is wrong, an exception raise up. The email address is the only one required field... I don't have sets and gets because user will setup all email data on constructor.

Now, i'm going to write the send tests. I don't know how to start it. How could i test if the values are there (subject, mail body, headers) if i don't want to have setters and getters? How could I test if an email could be sent?

Real world TDD examples are hard to me. I've tried to learn about it, i've read lots of things but i cannot test real code.

Thanks.

like image 842
thom Avatar asked Jun 14 '11 16:06

thom


People also ask

What is PHPUnit testing?

PHPUnit is a unit testing framework for the PHP programming language. It is an instance of the xUnit architecture for unit testing frameworks that originated with SUnit and became popular with JUnit. PHPUnit was created by Sebastian Bergmann and its development is hosted on GitHub.

Is PHPUnit a framework?

PHPUnit is a programmer-oriented testing framework for PHP. It is an instance of the xUnit architecture for unit testing frameworks. The currently supported versions are PHPUnit 9 and PHPUnit 8.

What is unit testing and how it is done?

Unit Testing is defined as a type of software testing where individual components of a software are tested. Unit Testing of the software product is carried out during the development of an application. An individual component may be either an individual function or a procedure.


1 Answers

Since you linked to the mail function, the call to mail is likely hardcoded into your code. So have a look at

  • http://sebastian-bergmann.de/archives/885-Stubbing-Hard-Coded-Dependencies.html

Install the testhelper extension and mock the call to mail. Then have the mock validate that it got called with the correct values when your wrapper's send method is called, e.g. define a custom mail function somewhere:

function mail_mock()
{
    $allThatWasPassedToTheFunction = func_get_args();
    return $allThatWasPassedToTheFunction;
}

Then in your send() test, do something like

public function testSendReceivesExpectedValues()
{
    // replace hardcoded call to mail() with mock function
    rename_function('mail', 'mail_orig');
    rename_function('mail_mock', 'mail');

    // use the wrapper
    $testClass = new MailWrapper('[email protected]');
    $results = $testClass->send();

    // assert the result
    $this->assertSame('[email protected]', $results[0]);
    $this->assertSame('Default Title', $results[1]);
    $this->assertSame('Default Message', $results[2]);
}

Note that the above assumes your send function will return the result of the mail() call.

In general, you will always try to substitute an external subsystem, like sendmail or a database or the filesystem with a Mock or a Stub, so you can concentrate on testing your own code in isolation of the external subsystem. You dont need to test that mail actually works.

Also see http://www.phpunit.de/manual/3.6/en/test-doubles.html

like image 65
Gordon Avatar answered Sep 29 '22 15:09

Gordon