<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Digital Sandwich &#187; PHP Testing</title>
	<atom:link href="http://digitalsandwich.com/archives/category/4-php/9-php-testing/feed" rel="self" type="application/rss+xml" />
	<link>http://digitalsandwich.com</link>
	<description>Forever Proving I am a Geek</description>
	<lastBuildDate>Sun, 01 Jan 2012 23:58:31 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Phake 1.0.0 is finished</title>
		<link>http://digitalsandwich.com/archives/100-phake-1-0-0-is-finished.html</link>
		<comments>http://digitalsandwich.com/archives/100-phake-1-0-0-is-finished.html#comments</comments>
		<pubDate>Sun, 01 Jan 2012 23:57:27 +0000</pubDate>
		<dc:creator>Mike Lively</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[PHP Testing]]></category>
		<category><![CDATA[phake]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://digitalsandwich.com/?p=100</guid>
		<description><![CDATA[So, now that 2012 is here, I can confidently say that I have accomplished two things&#8230;the first is proving that I can indeed completely neglect my site for a year. The second is that given a free weekend I can &#8230; <a href="http://digitalsandwich.com/archives/100-phake-1-0-0-is-finished.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[
<p>So, now that 2012 is here, I can confidently say that I have accomplished two things&#8230;the first is proving that I can indeed completely neglect my site for a year. The second is that given a free weekend I can still finish things. I just got done rolling the 1.0.0 stable release of <a href="http://phake.digitalsandwich.com/?p=59" title="Phake">Phake</a>.</p>
<p>I spent the better part of yesterday and today working out the last of the kinks and I am pretty happy with the results. It provides a great alternative mocking framework for PHPUnit that is compatible not just with older versions of PHPUnit but also older versions of PHP (5.2). You can look through my blog for some of my initial posts about it, or you can peruse the<a href="http://phake.digitalsandwich.com/docs/html/"> Phake documentation</a>. It allows you to do quite a few nifty things.</p>
<p>A big thanks to all those who have contributed feedback / code thus far.</p>
<p>Happy new year!</p>
<div class="topsy_widget_data topsy_theme_blue" style="float: left;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fdigitalsandwich.com%252Farchives%252F100-phake-1-0-0-is-finished.html%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FvCFyJu%22%2C%20%22style%22%3A%20%22small%22%2C%20%22title%22%3A%20%22Phake%201.0.0%20is%20finished%22%20%7D);"></div>

]]></content:encoded>
			<wfw:commentRss>http://digitalsandwich.com/archives/100-phake-1-0-0-is-finished.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pear Channel set up for Phake</title>
		<link>http://digitalsandwich.com/archives/93-pear-channel-set-up-for-phake.html</link>
		<comments>http://digitalsandwich.com/archives/93-pear-channel-set-up-for-phake.html#comments</comments>
		<pubDate>Fri, 31 Dec 2010 05:52:28 +0000</pubDate>
		<dc:creator>Mike Lively</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[PHP Testing]]></category>
		<category><![CDATA[phake]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[phpunit]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://digitalsandwich.com/?p=93</guid>
		<description><![CDATA[For those that may not have caught my first post on the subject, Phake is a mock framework that I announced a couple of days ago in Introducing Phake Mocking Framework. It was recommended in the comments that I get &#8230; <a href="http://digitalsandwich.com/archives/93-pear-channel-set-up-for-phake.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[
<p>For those that may not have caught my first post on the subject, <a href="https://github.com/mlively/Phake">Phake</a> is a mock framework that I announced a couple of days ago in <a href="http://digitalsandwich.com/archives/84-introducing-phake-mocking-framework.html">Introducing Phake Mocking Framework</a>. It was recommended in the comments that I get it on a pear channel somewhere, which is something I have wanted to do but hadn&#8217;t had a reason to do until this week. Well, now there is an official <a href="http://pear.digitalsandwich.com/">Digital Sandwich Pear Channel</a> that is hosting Phake. So if you want to play around with Phake you can install it like this:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">pear channel-discover pear.digitalsandwich.com<br />
pear install channel://pear.digitalsandwich.com/Phake-1.0.0alpha</div></div>
<p>Also, a couiple quick little side notes, the only reason I am still considering this an alpha is the lack of exhaustive, centralized documentation. The <a href="https://github.com/mlively/Phake/wiki">Phake Wiki</a> has some good details as does my previous post but I would like to get more official documentation up soon at which put it into a full beta. The api right now should be considered stable however. It will not be changing short of huge issues. We have been using it in production testing at my company for a little while no with great success. So, if the label of &#8216;alpha&#8217; makes you nervous, don&#8217;t worry. It&#8217;ll be okay.</p>
<p>Lastly, this library is compatible with PHP 5.2. I never really mentioned that in my last post either. It is not currently utilizing any php 5.3 functionality and I have no plans to break this backwards compatibility any time soon.</p>
<div class="topsy_widget_data topsy_theme_blue" style="float: left;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fdigitalsandwich.com%252Farchives%252F93-pear-channel-set-up-for-phake.html%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FeJe82j%22%2C%20%22style%22%3A%20%22small%22%2C%20%22title%22%3A%20%22Pear%20Channel%20set%20up%20for%20Phake%22%20%7D);"></div>

]]></content:encoded>
			<wfw:commentRss>http://digitalsandwich.com/archives/93-pear-channel-set-up-for-phake.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Introducing Phake Mocking Framework</title>
		<link>http://digitalsandwich.com/archives/84-introducing-phake-mocking-framework.html</link>
		<comments>http://digitalsandwich.com/archives/84-introducing-phake-mocking-framework.html#comments</comments>
		<pubDate>Wed, 29 Dec 2010 06:22:13 +0000</pubDate>
		<dc:creator>Mike Lively</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[PHP Testing]]></category>
		<category><![CDATA[phake]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[phpunit]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://digitalsandwich.com/?p=84</guid>
		<description><![CDATA[I have used PHPUnit heavily now for the last 4 years. As anyone that is heavily involved in writing Unit Tests knows, test doubles (commonly referred to as mock objects) are a necessary part of your toolbox. The mocking options &#8230; <a href="http://digitalsandwich.com/archives/84-introducing-phake-mocking-framework.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[
<p>I have used PHPUnit heavily now for the last 4 years. As anyone that is heavily involved in writing Unit Tests knows, test doubles (commonly referred to as mock objects) are a necessary part of your toolbox. The mocking options that we used to have for PHP unit testing have traditionally been fairly limited and most all of them in some form or another were ports of <a href="http://www.jmock.org/jmock1-getting-started.html">JMock</a>. The way PHP operates as well as some decisions made to more closely emulate how JMock does things lead to functionality in the existing mock library for PHPUnit that for some are a hassle. This ranges from PHPUnit implicitly calling the &#8220;mockee&#8217;s&#8221; constructor (you have to explicitly specify that you do not want to call the constructor) to the pain of trying to stub or verify multiple invocations of the same method with different parameters.</p>
<p>Over the last three years, my experience as well as the musing of some of my colleagues has led me to believe that a lot of what I don&#8217;t like about mocking in php is the result of the fundamental notions of combining stubbing with verification and setting expectations ahead of method calls instead of verifying that what you expected to happen has indeed happened. This was essentially proven to me over the last year and a half as I have been heavily working with Java code and as a result have been using the <a href="http://mockito.org/">Mockito</a> mocking library for Java. The result of this work is the <a href="https://github.com/mlively/Phake">Phake Mocking Framework</a>.</p>
<p>Now I am fairly certain that at least 5 or 6 people (which may constitute everyone who reads this) are rolling their eyes by now. So instead of going further into why I like this style of mocking I&#8217;ll just show you how to use it. Phake was designed with PHPUnit in mind, however I don&#8217;t really see any reason why it couldn&#8217;t be used in other testing frameworks as well. It is on my roadmap to confirm support for other frameworks. In any case, I will be using PHPUnit for my examples.</p>
<p>This document assumes you already have a good understanding of the basics of mocking. If the terms &#8216;Mocking&#8217;, &#8216;Stubbing&#8217;, and &#8216;Test Doubles&#8217; mean nothing to you, I would recommend checking out the following links:</p>
<ul>
<li><a href="http://www.phpunit.de/manual/current/en/test-doubles.html">PHPUnit on Mock Objects</a></li>
<li><a href="http://en.wikipedia.org/wiki/Mock_object">Wikipedia on Mock Objects</a></li>
<li><a href="http://www.google.com/search?client=ubuntu&#038;channel=fs&#038;q=What+are+Mock+Objects%3F&#038;ie=utf-8&#038;oe=utf-8">The Universe on Mock Objects</a></li>
</ul>
<h2>Getting Started</h2>
<p>You can get a copy of <a href="https://github.com/mlively/Phake">Phake</a> from Github. If you are familiar and comfortable with with git you can just clone my repository. If you would rather avoid the trappings of Github, you can also download <a href="https://github.com/mlively/Phake/tarball/latest">Phake&#8217;s latest release tarball</a>. Either way will result in a directory with two subdirectories: src and test. You will want to move the contents of the src directory to somewhere in your include path (such as /usr/share/php). Once you have done this, you can simply include &#8220;Phake.php&#8221; in any of your tests or in your bootstrap script and you will be off to the races.</p>
<hr />
<h3>UPDATE!!!</h3>
<p>I just set up a pear channel to distribute phake as well. So if you would like to install Phake using pear, just do the following:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">pear channel-discover pear.digitalsandwich.com<br />
pear install channel://pear.digitalsandwich.com/Phake-1.0.0alpha</div></div>
<hr />
<p>To show you some of the basics of how to use this framework, I am going to write various bits of codes to mock, verify, stub, etc the following class:</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<br />
<span style="color: #000000; font-weight: bold;">class</span> MyClass<br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">value</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getValue<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">value</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> subtract<span style="color: #009900;">&#40;</span><span style="color: #000088;">$int</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">value</span> <span style="color: #339933;">-</span> <span style="color: #000088;">$int</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></div>
<h2>Stubbing</h2>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<br />
<span style="color: #b1b100;">require_once</span> <span style="color: #0000ff;">'Phake.php'</span><span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">class</span> Test <span style="color: #000000; font-weight: bold;">extends</span> PHPUnit_Framework_TestCase<br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> testStubbingGetValue<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// Sets up the mock object.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// Analogous to $this-&gt;getMock() in PHPUnit</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$mock</span> <span style="color: #339933;">=</span> Phake<span style="color: #339933;">::</span><span style="color: #004000;">mock</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'MyClass'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// Builds the stub for getValue. </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// Essentially any call to getValue will return 42</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; Phake<span style="color: #339933;">::</span><span style="color: #004000;">when</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$mock</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">thenReturn</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">42</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">assertEquals</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">42</span><span style="color: #339933;">,</span> <span style="color: #000088;">$mock</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p>You can also do conditional stubbing based on passed in parameters.</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> testStubbingGetValue2<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$mock</span> <span style="color: #339933;">=</span> Phake<span style="color: #339933;">::</span><span style="color: #004000;">mock</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'MyClass'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// You can pass parameters into the stubbed method to indicate you</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// only want to stub matching invocations. By default, anything </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// passed in must be loosely matched ('==')</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; Phake<span style="color: #339933;">::</span><span style="color: #004000;">when</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$mock</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">subtract</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">42</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">thenReturn</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">30</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">assertEquals</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">30</span><span style="color: #339933;">,</span> <span style="color: #000088;">$mock</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">subtract</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">42</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// It is important to note that any unstubbed calls will return null.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// Since 41 != 42 this call will return null.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">assertNull</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$mock</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">subtract</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">41</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span></div></div>
<p>If a specific invocation or call of a mock object has not been stubbed, it will return null. This behavior is different than the default behavior of PHPUnit&#8217;s mocking framework. If you need the default PHPUnit behavior then you could use something called partial mocks. Partial mocks are setup to call the constructor of the class being mocked and for any call that has not been stubbed, the parent method will be called.</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> testStubbingGetValue3<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// Creates a mock object whose constructor will call </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// MyClass::__construct(42);</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$mock</span> <span style="color: #339933;">=</span> Phake<span style="color: #339933;">::</span><span style="color: #004000;">partMock</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'MyClass'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">42</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; Phake<span style="color: #339933;">::</span><span style="color: #004000;">when</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$mock</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">subtract</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">42</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">thenReturn</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// Since 18 != 42, the real method gets call </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">assertEquals</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">24</span><span style="color: #339933;">,</span> <span style="color: #000088;">$mock</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">subtract</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">18</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span></div></div>
<p>You can also specify on a per call basis that you want to call the parent, using the thenCallParent() method instead of thenReturn(). The different values you can use for stubbing are referred to as &#8216;Answers&#8217;. Here are a list of them and what they will do when a matching invocation is called:</p>
<ul>
<li><strong>thenReturn(mixed $var)</strong> &#8211; Will return the exact value passed in.</li>
<li><strong>thenCallParent()</strong> &#8211; Will return the results of calling the mocked parent method.</li>
<li><strong>thenThrow(Exception $e)</strong> &#8211; Will throw $e.</li>
<li><strong>captureReturnTo(&#038;$variable)</strong> &#8211; Acts exactly like thenCallParent() however it also captures the value that the parent returned to $variable. This allows you to run assertions. This comes in very handy for testing legacy code with protected or private factory methods whose return values are never returned out of the tested method&#8217;s scope.</li>
</ul>
<p>The other thing to take note of stubbing is that any PHPUnit constraints are supported.</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> testStubbingGetValue4<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$mock</span> <span style="color: #339933;">=</span> Phake<span style="color: #339933;">::</span><span style="color: #004000;">mock</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'MyClass'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//Matches any call to subtract() where the passed in value equals 42</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; Phake<span style="color: #339933;">::</span><span style="color: #004000;">when</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$mock</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">subtract</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">42</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">thenReturn</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">30</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//Matches any call to subtract() where the passed in value is less </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// than 42. Notice that this is a phpunit constraint</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; Phake<span style="color: #339933;">::</span><span style="color: #004000;">when</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$mock</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">subtract</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">lessThan</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">42</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">thenReturn</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">29</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">assertEquals</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">30</span><span style="color: #339933;">,</span> <span style="color: #000088;">$mock</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">subtract</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">42</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">assertEquals</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">29</span><span style="color: #339933;">,</span> <span style="color: #000088;">$mock</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">subtract</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">41</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span></div></div>
<p>This gives you the same kind of stubbing flexibility that you have present in PHPUnit.</p>
<h2>Verification</h2>
<p>Verifying that methods on your stub are called is starkly different then how it is done in PHPUnit. The most apparent symptom of this difference is that you verify calls <em>after</em> the calls to your test methods have been made.</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> testVerify1<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// You can apply stubbings and verifications to the same mock objects</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$mock</span> <span style="color: #339933;">=</span> Phake<span style="color: #339933;">::</span><span style="color: #004000;">mock</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'MyClass'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$mock</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//Notice, getValue() has already been called</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; Phake<span style="color: #339933;">::</span><span style="color: #004000;">verify</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$mock</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span></div></div>
<p>You of course have the same matching functionality at your disposal.</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> testVerify2<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$mock</span> <span style="color: #339933;">=</span> Phake<span style="color: #339933;">::</span><span style="color: #004000;">mock</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'MyClass'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$mock</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">subtract</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">40</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//Notice the constraint</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; Phake<span style="color: #339933;">::</span><span style="color: #004000;">verify</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$mock</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">subtract</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">lessThan</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">42</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span></div></div>
<p>By default, verify only allows a single matching invocation. You can also specify that a specific number of invocations should be allowed.</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> testVerify3<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$mock</span> <span style="color: #339933;">=</span> Phake<span style="color: #339933;">::</span><span style="color: #004000;">mock</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'MyClass'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$mock</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">subtract</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">40</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$mock</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">subtract</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">39</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//The number of times is passed as the second parameter of </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//Phake::verify()</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; Phake<span style="color: #339933;">::</span><span style="color: #004000;">verify</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$mock</span><span style="color: #339933;">,</span> Phake<span style="color: #339933;">::</span><span style="color: #004000;">times</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">subtract</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">lessThan</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">42</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span></div></div>
<p>You can also use Phake::atLeast($n) and Phake::atMost($n) instead of Phake::times($n).</p>
<p>You can also specify that you don&#8217;t expect there to be any interactions with a mock.</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> testVerify4<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$mock</span> <span style="color: #339933;">=</span> Phake<span style="color: #339933;">::</span><span style="color: #004000;">mock</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'MyClass'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// This will ensure that UP TO THIS POINT no methods on $mock have </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// been called</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; Phake<span style="color: #339933;">::</span><span style="color: #004000;">verifyNoInteraction</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$mock</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// This would not result in an error, this can be prevented with </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// another method explained below</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$mock</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span></div></div>
<p>I am sure you noticed the comment that Phake::verifyNoInteraction() only verifies that no calls were made up to that point. You can essentially <em>freeze</em> a mock with another method</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> testVerify5<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$mock</span> <span style="color: #339933;">=</span> Phake<span style="color: #339933;">::</span><span style="color: #004000;">mock</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'MyClass'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$mock</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// This will ensure that no methods on $mock will be called after this </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// point</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; Phake<span style="color: #339933;">::</span><span style="color: #004000;">verifyNoFurtherInteraction</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$mock</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span></div></div>
<p>There are a few more advanced things you can do with something called argument captors.</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> testVerify6<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$mock</span> <span style="color: #339933;">=</span> Phake<span style="color: #339933;">::</span><span style="color: #004000;">mock</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'MyClass'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$mock</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">subtract</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">42</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// Phake::capture tells Phake to store the parameter passed to </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// subtract as the variable $val</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; Phake<span style="color: #339933;">::</span><span style="color: #004000;">verify</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$mock</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">subtract</span><span style="color: #009900;">&#40;</span>Phake<span style="color: #339933;">::</span><span style="color: #004000;">capture</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$val</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">assertEquals</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">42</span><span style="color: #339933;">,</span> <span style="color: #000088;">$val</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span></div></div>
<p>This is a very pedestrian example, but it is not that uncommon for fairly complicated objects to passed in and out of methods. Argument capturing allows you to much more succinctly assert the state of those types of parameters. It is definitely overkill for asserting scalar types or simple objects.</p>
<h2>More to Come</h2>
<p>This really does cover the very basics of the Phake framework. In the coming days I will be putting out smaller more focused articles discussing some of the specific functionality. In the meantime I would love to get some feedback from anyone who is brave enough to play with this. My future roadmap basically involves shoring up the current code base a little bit more, adding a few pieces of missing or suboptimal functionality (I&#8217;m not so sure I have implemented &#8216;consecutive calls&#8217;) but I anticipate releasing an RC version no later than the end of January. Also, I am currently using and monitoring the <a href="https://github.com/mlively/Phake/issues">issue tracker for Phake</a> at github, so if you have some functionality you would like or find any bugs in your exploring, you can also open an issue there. Also, if you would like to help out with contributions, they are certainly welcome.</p>
<div class="topsy_widget_data topsy_theme_blue" style="float: left;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fdigitalsandwich.com%252Farchives%252F84-introducing-phake-mocking-framework.html%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FfT7goN%22%2C%20%22style%22%3A%20%22small%22%2C%20%22title%22%3A%20%22Introducing%20Phake%20Mocking%20Framework%22%20%7D);"></div>

]]></content:encoded>
			<wfw:commentRss>http://digitalsandwich.com/archives/84-introducing-phake-mocking-framework.html/feed</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
		<item>
		<title>YAML Now Supported by PHPUnit Database Extension</title>
		<link>http://digitalsandwich.com/archives/79-yaml-now-supported-by-phpunit-database-extension.html</link>
		<comments>http://digitalsandwich.com/archives/79-yaml-now-supported-by-phpunit-database-extension.html#comments</comments>
		<pubDate>Sun, 01 Feb 2009 18:22:13 +0000</pubDate>
		<dc:creator>Mike Lively</dc:creator>
				<category><![CDATA[PHP Testing]]></category>

		<guid isPermaLink="false">http://digitalsandwich.com/?p=79</guid>
		<description><![CDATA[I have now just committed YAML data sets to the Database Extension for PHPUnit. So now all those that love the simplicity and straightforwardness of YAML can use it with your data sets. I have also created a persistor for &#8230; <a href="http://digitalsandwich.com/archives/79-yaml-now-supported-by-phpunit-database-extension.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[
<p>I have now just committed <a href="http://yaml.org/">YAML</a> data sets to the Database Extension for <a href="http://www.phpun.it">PHPUnit</a>. So now all those that love the simplicity and straightforwardness of YAML can use it with your data sets. I have also created a persistor for YAML datasets so you can easily convert existing data sets or database data into YAML representations.</p>
<p>This is really the first I have dealt with YAML and it is definitely a viable alternative for data sets. Here is what they will look like.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">table1:<br />
&nbsp; -<br />
&nbsp; &nbsp; table1_id: 1<br />
&nbsp; &nbsp; columnName1: &quot;tgfahgasdf&quot;<br />
&nbsp; &nbsp; columnName2: 200<br />
&nbsp; &nbsp; columnName3: 34.64<br />
&nbsp; &nbsp; columnName4: yghkf;a &nbsp;hahfg8ja h;<br />
table2:<br />
&nbsp; -<br />
&nbsp; &nbsp; table2_id: 1<br />
&nbsp; &nbsp; column5: fhah<br />
&nbsp; &nbsp; column6: 456<br />
&nbsp; &nbsp; column7: 46.5<br />
&nbsp; &nbsp; column8: &quot;fsdb, ghfdas&quot;<br />
&nbsp; -<br />
&nbsp; &nbsp; table2_id: 3<br />
&nbsp; &nbsp; column5: ajsdlkfguitah<br />
&nbsp; &nbsp; column6: 654<br />
&nbsp; &nbsp; column7: blah<br />
&nbsp; &nbsp; column8: |-<br />
&nbsp; &nbsp; &nbsp; thesethasdl<br />
&nbsp; &nbsp; &nbsp; asdflkjsadf asdfsadfhl &quot;adsf, halsdf&quot; sadfhlasdf</div></div>
<p>The biggest issue I had was figuring out how YAML dealt with trailing line breaks. It appears that &#8216;|-&#8217; did the trick. It will strip the final line break. Another thing to take note is that indention is important. It doesn&#8217;t HAVE to be spaces (it can be tabs) it just needs to be consistent. The last thing is that strings do not need to be quoted, but if they are you can use escape characters (like \n.)</p>
<p>This was committed to the trunk of PHPUnit and I anticipate Sebastian will be merging it back into 3.4 shortly.</p>
<div class="topsy_widget_data topsy_theme_blue" style="float: left;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fdigitalsandwich.com%252Farchives%252F79-yaml-now-supported-by-phpunit-database-extension.html%22%2C%20%22style%22%3A%20%22small%22%2C%20%22title%22%3A%20%22YAML%20Now%20Supported%20by%20PHPUnit%20Database%20Extension%22%20%7D);"></div>

]]></content:encoded>
			<wfw:commentRss>http://digitalsandwich.com/archives/79-yaml-now-supported-by-phpunit-database-extension.html/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Improved PHPUnit Filters</title>
		<link>http://digitalsandwich.com/archives/78-improved-phpunit-filters.html</link>
		<comments>http://digitalsandwich.com/archives/78-improved-phpunit-filters.html#comments</comments>
		<pubDate>Sun, 01 Feb 2009 04:54:28 +0000</pubDate>
		<dc:creator>Mike Lively</dc:creator>
				<category><![CDATA[PHP Testing]]></category>

		<guid isPermaLink="false">http://digitalsandwich.com/?p=78</guid>
		<description><![CDATA[I have finally gotten some time to do some long awaited work on PHPUnit. The first on my agenda was a small improvement to filtering. This was related to ticket #526. Essentially I added the ability to do both white &#8230; <a href="http://digitalsandwich.com/archives/78-improved-phpunit-filters.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[
<p>I have finally gotten some time to do some long awaited work on PHPUnit. The first on my agenda was a small improvement to filtering. This was related to <a href="http://www.phpunit.de/ticket/526">ticket #526</a>. Essentially I added the ability to do both white list and black list filtering.
</p>
<p>For instance, if you wanted to specify an include filter you can do the following:</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">&lt;?php</span> <br />
<span style="color: #666666; font-style: italic;">//... </span><br />
<br />
<span style="color: #000088;">$filteredDataSet</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> PHPUnit_Extensions_Database_DataSet_DataSetFilter<span style="color: #009900;">&#40;</span><span style="color: #000088;">$dataSet</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000088;">$filteredDataSet</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addIncludeTables</span><span style="color: #009900;">&#40;</span><a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'table1'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'table3'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <br />
<span style="color: #000088;">$filteredDataSet</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setIncludeColumnsForTable</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'table1'</span><span style="color: #339933;">,</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'column1'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'column2'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'column3'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'column4'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <br />
<span style="color: #000088;">$filteredDataSet</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setIncludeColumnsForTable</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'table3'</span><span style="color: #339933;">,</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'column9'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'column10'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'column11'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'column12'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #666666; font-style: italic;">//... </span><br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></div>
<p>I have also deprecated passing the filter to the constructor. The reason for this is that I would like to begin adding a few more features to the filter and the current method of passing the parameters on the constructor would be unintuitive for these planned features. Basically I think it was a mistake for me to allow the passing of filter data on the constructor to begin with. I anticipate the current method working up to PHPUnit 4.0 but it will not be expanded on and will be removed either in PHPUnit 4 or in a release soon after that.
</p>
<p>So, for exclude filters, instead of specifying them in the constructor, the new method will be:</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">&lt;?php</span> <br />
<span style="color: #666666; font-style: italic;">//...</span><br />
<br />
<span style="color: #000088;">$filteredDataSet</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> PHPUnit_Extensions_Database_DataSet_DataSetFilter<span style="color: #009900;">&#40;</span><span style="color: #000088;">$dataSet</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000088;">$filteredDataSet</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addExcludeTables</span><span style="color: #009900;">&#40;</span><a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'table2'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <br />
<span style="color: #000088;">$filteredDataSet</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setExcludeColumnsForTable</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'table1'</span><span style="color: #339933;">,</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'table1_id'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <br />
<span style="color: #000088;">$filteredDataSet</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setExcludeColumnsForTable</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'table3'</span><span style="color: #339933;">,</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'table3_id'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #666666; font-style: italic;">//... </span><br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></div>
<p>While you can&#8217;t mix include and exclude filters for tables (wouldn&#8217;t make sense right now) you CAN do this for table columns of separate tables:</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">&lt;?php</span> <br />
<span style="color: #666666; font-style: italic;">//...</span><br />
<br />
<span style="color: #000088;">$filteredDataSet</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> PHPUnit_Extensions_Database_DataSet_DataSetFilter<span style="color: #009900;">&#40;</span><span style="color: #000088;">$dataSet</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000088;">$filteredDataSet</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addIncludeTables</span><span style="color: #009900;">&#40;</span><a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'table1'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'table3'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <br />
<span style="color: #000088;">$filteredDataSet</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setExcludeColumnsForTable</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'table1'</span><span style="color: #339933;">,</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'table1_id'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <br />
<span style="color: #000088;">$filteredDataSet</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setIncludeColumnsForTable</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'table3'</span><span style="color: #339933;">,</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'column9'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'column10'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'column11'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'column12'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #666666; font-style: italic;">//... </span><br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></div>
<p>Some future features I plan on adding include, global column includes/excludes and wild cards. Anyhow, hope this is useful for someone.</p>
<div class="topsy_widget_data topsy_theme_blue" style="float: left;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fdigitalsandwich.com%252Farchives%252F78-improved-phpunit-filters.html%22%2C%20%22style%22%3A%20%22small%22%2C%20%22title%22%3A%20%22Improved%20PHPUnit%20Filters%22%20%7D);"></div>

]]></content:encoded>
			<wfw:commentRss>http://digitalsandwich.com/archives/78-improved-phpunit-filters.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>2008 DC PHP Conference &#8211; Advanced PHPUnit Testing</title>
		<link>http://digitalsandwich.com/archives/74-2008-dc-php-conference-advanced-phpunit-testing.html</link>
		<comments>http://digitalsandwich.com/archives/74-2008-dc-php-conference-advanced-phpunit-testing.html#comments</comments>
		<pubDate>Wed, 04 Jun 2008 13:55:41 +0000</pubDate>
		<dc:creator>Mike Lively</dc:creator>
				<category><![CDATA[PHP Testing]]></category>

		<guid isPermaLink="false">http://digitalsandwich.com/?p=74</guid>
		<description><![CDATA[And here are the advanced PHPUnit slides! &#124; View &#124; Upload your own]]></description>
			<content:encoded><![CDATA[
<p>And here are the advanced PHPUnit slides!</p>
<div id="__ss_446619" style="width: 425px; text-align: left;"><object width="425" height="355" style="margin: 0px;"><param value="http://static.slideshare.net/swf/ssplayer2.swf?doc=advanced-php-unit-testing2-1212587249704441-9" name="movie" /><param value="true" name="allowFullScreen" /><param value="always" name="allowScriptAccess" /><embed width="425" height="355" allowfullscreen="true" allowscriptaccess="always" type="application/x-shockwave-flash" src="http://static.slideshare.net/swf/ssplayer2.swf?doc=advanced-php-unit-testing2-1212587249704441-9" /></object>
<div style="font-size: 11px; font-family: tahoma,arial; height: 26px; padding-top: 2px;"><a href="http://www.slideshare.net/?src=embed"><img alt="SlideShare" style="border: 0px none ; margin-bottom: -5px;" src="http://static.slideshare.net/swf/logo_embd.png" /></a> | <a title="View Advanced PHPUnit Testing on SlideShare" href="http://www.slideshare.net/mjlivelyjr/advanced-phpunit-testing?src=embed">View</a> | <a href="http://www.slideshare.net/upload?src=embed">Upload your own</a></div>
</div>
<div class="topsy_widget_data topsy_theme_blue" style="float: left;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fdigitalsandwich.com%252Farchives%252F74-2008-dc-php-conference-advanced-phpunit-testing.html%22%2C%20%22style%22%3A%20%22small%22%2C%20%22title%22%3A%20%222008%20DC%20PHP%20Conference%20-%20Advanced%20PHPUnit%20Testing%22%20%7D);"></div>

]]></content:encoded>
			<wfw:commentRss>http://digitalsandwich.com/archives/74-2008-dc-php-conference-advanced-phpunit-testing.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>2008 DC PHP Conference &#8211; Automated Unit Testing</title>
		<link>http://digitalsandwich.com/archives/73-2008-dc-php-conference-automated-unit-testing.html</link>
		<comments>http://digitalsandwich.com/archives/73-2008-dc-php-conference-automated-unit-testing.html#comments</comments>
		<pubDate>Wed, 04 Jun 2008 13:52:32 +0000</pubDate>
		<dc:creator>Mike Lively</dc:creator>
				<category><![CDATA[PHP Testing]]></category>

		<guid isPermaLink="false">http://digitalsandwich.com/?p=73</guid>
		<description><![CDATA[As promised here are my automated unit testing slides for the 2008 DC PHP conference. &#124; View &#124; Upload your own]]></description>
			<content:encoded><![CDATA[
<p>As promised here are my automated unit testing slides for the 2008 DC PHP conference.</p>
<div style="width:425px;text-align:left" id="__ss_446614"><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=automated-unit-testing-1212587126813053-9"/><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slideshare.net/swf/ssplayer2.swf?doc=automated-unit-testing-1212587126813053-9" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object>
<div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;"><a href="http://www.slideshare.net/?src=embed"><img src="http://static.slideshare.net/swf/logo_embd.png" style="border:0px none;margin-bottom:-5px" alt="SlideShare"/></a> | <a href="http://www.slideshare.net/mjlivelyjr/automated-unit-testing?src=embed" title="View Automated Unit Testing on SlideShare">View</a> | <a href="http://www.slideshare.net/upload?src=embed">Upload your own</a></div>
</div>
<div class="topsy_widget_data topsy_theme_blue" style="float: left;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fdigitalsandwich.com%252Farchives%252F73-2008-dc-php-conference-automated-unit-testing.html%22%2C%20%22style%22%3A%20%22small%22%2C%20%22title%22%3A%20%222008%20DC%20PHP%20Conference%20-%20Automated%20Unit%20Testing%22%20%7D);"></div>

]]></content:encoded>
			<wfw:commentRss>http://digitalsandwich.com/archives/73-2008-dc-php-conference-automated-unit-testing.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Adding Database Tests to Existing PHPUnit Test Cases</title>
		<link>http://digitalsandwich.com/archives/64-adding-database-tests-to-existing-phpunit-test-cases.html</link>
		<comments>http://digitalsandwich.com/archives/64-adding-database-tests-to-existing-phpunit-test-cases.html#comments</comments>
		<pubDate>Wed, 05 Sep 2007 04:00:00 +0000</pubDate>
		<dc:creator>Mike Lively</dc:creator>
				<category><![CDATA[PHP Testing]]></category>

		<guid isPermaLink="false">http://digitalsandwich.com/?p=64</guid>
		<description><![CDATA[When I was first creating the Database Extension for PHPUnit I realized that there was a very high likelihood that several people would have tests that were already written that they would like to add additional database tests too. To &#8230; <a href="http://digitalsandwich.com/archives/64-adding-database-tests-to-existing-phpunit-test-cases.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[
<p>When I was first creating the <a href="http://www.ds-o.com/archives/63-PHPUnit-Database-Extension-DBUnit-Port.html" title="PHPUnit Database Extensions (DBUnit Port)">Database Extension</a> for <a href="http://www.phpunit.de" title="PHPUnit">PHPUnit</a> I realized that there was a very high likelihood that several people would have tests that were already written that they would like to add additional database tests too. To accomplish this I actually wrote the <b>PHPUnit_Extensions_Database_DefaultTester</b> class. In fact, if you were to look at the source of the database test case you will see that all of it&#8217;s operations are actually forwarded to this class which does all of the work.</p>
<p>Please continue reading to see how you can use composition to add database tests to your existing test cases.</p>
<p><span id="more-64"></span></p>
<p>So, now you might be wondering how can I use this class to add data-centric tests to my existing test case. I am going to use the BankAccount example that exists in PHPUnit to show you. Below you can find the existing bank account test case (without comments.)</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">require_once 'PHPUnit/Framework/TestCase.php';<br />
require_once 'BankAccount.php';<br />
<br />
class BankAccountTest extends PHPUnit_Framework_TestCase<br />
{<br />
&nbsp; &nbsp; protected $ba;<br />
<br />
&nbsp; &nbsp; protected function setUp()<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; $this-&gt;ba = new BankAccount;<br />
&nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; public function testBalanceIsInitiallyZero()<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; $this-&gt;assertEquals(0, $this-&gt;ba-&gt;getBalance());<br />
&nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; public function testBalanceCannotBecomeNegative()<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; try {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $this-&gt;ba-&gt;withdrawMoney(1);<br />
&nbsp; &nbsp; &nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; catch (BankAccountException $e) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $this-&gt;assertEquals(0, $this-&gt;ba-&gt;getBalance());<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return;<br />
&nbsp; &nbsp; &nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; $this-&gt;fail();<br />
&nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; public function testBalanceCannotBecomeNegative2()<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; try {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $this-&gt;ba-&gt;depositMoney(-1);<br />
&nbsp; &nbsp; &nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; catch (BankAccountException $e) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $this-&gt;assertEquals(0, $this-&gt;ba-&gt;getBalance());<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return;<br />
&nbsp; &nbsp; &nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; $this-&gt;fail();<br />
&nbsp; &nbsp; }<br />
}</div></div>
<p>I would like to add a test to see if a bank account is created in the database when the bank account&#8217;s constructor is called. This is the same test I showed you in my first example of the database extension. However, I do not want to add the overhead of creating and seeding the database for my existing tests that obviously doesn&#8217;t need them. I should tell you right away that I would actually prefer in these cases to just create a new test case to handle just the data-centric tests. However, one thing using composition will assist greatly with is if you want to test database code that should throw exceptions as well as perform data operations. I am sure there are many other valid uses that I haven&#8217;t even thought of as well.</p>
<p>First thing I need to do is add an instance of <b>PHPUnit_Extensions_Database_DefaultTester</b> to the test case. To create a tester instance I will need to have a pdo connection. For this example I am going to use a database I created on my local machine in mysql.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">class BankAccountTest extends PHPUnit_Framework_TestCase<br />
{<br />
&nbsp; &nbsp; // ...<br />
&nbsp; &nbsp; protected function getDatabaseTester()<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; $pdo = new PDO('mysql:host=localhost;dbname=test', 'root', '');<br />
&nbsp; &nbsp; &nbsp; &nbsp; $connection = new PHPUnit_Extensions_Database_DB_DefaultDatabaseConnection($pdo, 'test');<br />
&nbsp; &nbsp; &nbsp; &nbsp; return new PHPUnit_Extensions_Database_DefaultTester($connection);<br />
&nbsp; &nbsp; }<br />
&nbsp; &nbsp; // ...<br />
}</div></div>
<p />
<p>I will now need to specify the different events that will occur on startUp and tearDown of the new test and the data that will be used. To do this I am going to add a few calls to the tester in my <b>getDatabaseTester</b>() method. The first method, <b>setSetUpOperation</b>(), will tell the tester which operation I would like to perform on the database at the start of each test. Likewise, the second method <b>setTearDownOperation</b>() will tell the tester which operation to perform on the database at the end of each test. Both of these methods will accept an object implementing <b>PHPUnit_Extensions_Database_Operation_IDatabaseOperation</b>. The most common one you will probably want to use is the &#8216;clean insert&#8217; operation. This operation will perform a truncate on each table in your data set and then insert all rows in the dataset. I am going to use a factory class to generate the operation. If you want to view all of the current operations available I recommend browsing the following src directory: <a title="Database Extension Operations" href="http://www.phpunit.de/browser/phpunit/branches/3.2/PHPUnit/Extensions/Database/Operation">http://www.phpunit.de/browser/phpunit/branches/3.2/PHPUnit/Extensions/Database/Operation</a>. The final method we will need to call is <b>setDataSet</b>(). This will<br />
 accept any of the data set objects. I am just going to use a flat xml data set with a few rows.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;dataset&gt;<br />
&nbsp; &nbsp; &lt;bank_account account_number=&quot;15934903649620486&quot; balance=&quot;100.00&quot;&gt;<br />
&nbsp; &nbsp; &lt;bank_account account_number=&quot;15936487230215067&quot; balance=&quot;1216.00&quot;&gt;<br />
&nbsp; &nbsp; &lt;bank_account account_number=&quot;12348612357236185&quot; balance=&quot;89.00&quot;&gt;<br />
&lt;/bank_account&gt;</div></div>
<p></bank_account></bank_account></dataset>
<p>So with these new changes our <b>getDatabaseTester</b>() method will look like this:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">require_once 'PHPUnit/Framework/TestCase.php';<br />
require_once 'BankAccount.php';<br />
<br />
class BankAccountTest extends PHPUnit_Framework_TestCase<br />
{<br />
&nbsp; &nbsp; // ...<br />
&nbsp; &nbsp; protected function getDatabaseTester()<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; $pdo = new PDO('mysql:host=localhost;dbname=test', 'root', '');<br />
&nbsp; &nbsp; &nbsp; &nbsp; $connection = new PHPUnit_Extensions_Database_DB_DefaultDatabaseConnection($pdo, 'test');<br />
&nbsp; &nbsp; &nbsp; &nbsp; $tester = new PHPUnit_Extensions_Database_DefaultTester($connection);<br />
&nbsp; &nbsp; &nbsp; &nbsp; $tester-&gt;setSetUpOperation(PHPUnit_Extensions_Database_Operation_Factory::CLEAN_INSERT());<br />
&nbsp; &nbsp; &nbsp; &nbsp; $tester-&gt;setTearDownOperation(PHPUnit_Extensions_Database_Operation_Factory::NONE());<br />
&nbsp; &nbsp; &nbsp; &nbsp; $tester-&gt;setDataSet(new PHPUnit_Extensions_Database_DataSet_FlatXMLDataSet(dirname(__FILE__).'/_files/bank-account-seed.xml'));<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; return $tester;<br />
&nbsp; &nbsp; }<br />
&nbsp; &nbsp; // ...<br />
}</div></div>
<p>You will notice that I used an operation called <b>NONE</b>() on teardown. This, as you may have guessed, is a NULL operation. It does absolutely nothing which in this case is perfectly alright since we are truncating at the the beginning of each test.</p>
<p>Now I am ready to add my new test method. In this test I am going to call my <b>getDatabaseTester</b>(). I will the call the <b>onSetUp</b>() method of the tester. This will perform the setup  operation that we specified previously. Then I will create a new bank account, retrieve a dataset from the connection I created in <b>getDatabaseTester</b>() (utilizing the <b>getConnection</b>() method,) and compare the results using the <b>assertDataSetsEqual</b>() static method of the Database TestCase class. Finally I will clean up my mess (which in this case means nothing) using the <b>onTearDown</b>() method of the tester object.</p>
<p>You will notice that I have access to the two asserts of the database test case. They are static, public methods and can be accessed from anywhere.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">require_once 'PHPUnit/Framework/TestCase.php';<br />
require_once 'BankAccount.php';<br />
<br />
class BankAccountTest extends PHPUnit_Framework_TestCase<br />
{<br />
&nbsp; &nbsp; // ...<br />
&nbsp; &nbsp; protected function getDatabaseTester()<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; $pdo = new PDO('mysql:host=localhost;dbname=test', 'root', '');<br />
&nbsp; &nbsp; &nbsp; &nbsp; $connection = new PHPUnit_Extensions_Database_DB_DefaultDatabaseConnection($pdo, 'test');<br />
&nbsp; &nbsp; &nbsp; &nbsp; $tester = new PHPUnit_Extensions_Database_DefaultTester($connection);<br />
&nbsp; &nbsp; &nbsp; &nbsp; $tester = new PHPUnit_Extensions_Database_DefaultTester($pdo);<br />
&nbsp; &nbsp; &nbsp; &nbsp; $tester-&gt;setSetUpOperation(PHPUnit_Extensions_Database_Operation_Factory::CLEAN_INSERT());<br />
&nbsp; &nbsp; &nbsp; &nbsp; $tester-&gt;setTearDownOperation(PHPUnit_Extensions_Database_Operation_Factory::NONE());<br />
&nbsp; &nbsp; &nbsp; &nbsp; $tester-&gt;setDataSet(new PHPUnit_Extensions_Database_DataSet_FlatXMLDataSet(dirname(__FILE__).'/_files/bank-account-seed.xml'));<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; return $tester;<br />
&nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; public function testNewAccountCreation()<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; $tester = $this-&gt;getDatabaseTester();<br />
&nbsp; &nbsp; &nbsp; &nbsp; $tester-&gt;onSetUp();<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; $bank_account = new BankAccount('12345678912345678', new PDO('mysql:host=localhost;dbname=test', 'root', ''));<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; $xml_dataset = $this-&gt;createFlatXMLDataSet(dirname(__FILE__).'/_files/bank-account-after-new-account.xml');<br />
&nbsp; &nbsp; &nbsp; &nbsp; PHPUnit_Extensions_Database_TestCase::assertDataSetsEqual($xml_dataset, $tester-&gt;getConnection()-&gt;createDataSet());<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; $tester-&gt;onTearDown();<br />
&nbsp; &nbsp; }<br />
&nbsp; &nbsp; // ...<br />
}</div></div>
<p>That&#8217;s all there is to it. Now you can just go nuts adding new database tests or plain old php tests only incurring the database overhead when needed.</p>
<div class="topsy_widget_data topsy_theme_blue" style="float: left;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fdigitalsandwich.com%252Farchives%252F64-adding-database-tests-to-existing-phpunit-test-cases.html%22%2C%20%22style%22%3A%20%22small%22%2C%20%22title%22%3A%20%22Adding%20Database%20Tests%20to%20Existing%20PHPUnit%20Test%20Cases%22%20%7D);"></div>

]]></content:encoded>
			<wfw:commentRss>http://digitalsandwich.com/archives/64-adding-database-tests-to-existing-phpunit-test-cases.html/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>PHPUnit Database Extension (DBUnit Port)</title>
		<link>http://digitalsandwich.com/archives/63-phpunit-database-extension-dbunit-port.html</link>
		<comments>http://digitalsandwich.com/archives/63-phpunit-database-extension-dbunit-port.html#comments</comments>
		<pubDate>Sun, 02 Sep 2007 19:55:16 +0000</pubDate>
		<dc:creator>Mike Lively</dc:creator>
				<category><![CDATA[PHP Testing]]></category>

		<guid isPermaLink="false">http://digitalsandwich.com/?p=63</guid>
		<description><![CDATA[I have completed the initial feature set for the Database extension to PHPUnit. This is a essentially a port of DBUnit to PHP. For those that may not have read any of my previous postings on the subject the goal &#8230; <a href="http://digitalsandwich.com/archives/63-phpunit-database-extension-dbunit-port.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[
<p>I have completed the initial feature set for the Database extension to <a href="http://www.phpunit.de" title="PHPUnit">PHPUnit</a>. This is a essentially a port of <a href="http://dbunit.sourceforge.net/" title="DBUnit">DBUnit</a> to <a href="http://www.php.net">PHP</a>.</p>
<p>For those that may not have read any of my <a href="http://www.ds-o.com/archives/62-PHPDBUnit-Testing-DB-interaction-with-PHPUnit.html" title="PHPDBUnit Testing DB interaction with PHPUnit">previous postings</a> on the subject the goal of this software is to extend the functionality of PHPUnit to allow using seed data to put a given database into a known state prior to executing each test. It also provides an easy mechanism to compare database contents with an expected dataset.</p>
<p>The database extension has recently been merged into the PHPUnit 3.2 branch and is scheduled to be released in that version. <a href="http://sebastian-bergmann.de/" title="Sebastian Bergmann">Sebastian Bergmann</a> will be introducing the extension in his <a title="Advanced Testing with PHPUnit" href="http://works.phparch.com/c/schedule/talk/d2s5/0">Advanced Testing with PHPUnit</a> talk at <a title="PHP|Works 2007" href="http://works.phparch.com/c/p/index">PHP|Works 2007</a> in Atlanta September 13 &#8211; 14. If you would like to tinker around with the database extension prior to it&#8217;s release you can always download the latest copy of PHPUnit 3.2 from svn: svn://svn.phpunit.de/phpunit/phpunit/branches/3.2. The source can also be browsed at <a href="http://www.phpunit.de/browser/phpunit/branches/3.2/PHPUnit/Extensions/Database">http://www.phpunit.de/browser/phpunit/branches/3.2/PHPUnit/Extensions/Database</a>.</p>
<p>Please continue reading for an example of how you can now use PHPUnit to even more effectively test data-centric applications.</p>
<p><span id="more-63"></span></p>
<p>In this example I am going show you how to create a new test case to test the database functionality of a class providing functionality to edit the details of a bank account.</p>
<p>To use the database extension I will create a new test case extending the class <b>PHPUnit_Extensions_Database_TestCase</b>.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">require_once 'PHPUnit/Extensions/Database/TestCase.php';<br />
<br />
class BankAccountDBTest extends PHPUnit_Extensions_Database_TestCase<br />
{<br />
}</div></div>
<p>There are two methods that you must have in any database test case. Those methods are <b>getConnection()</b> and <b>getDataSet()</b>. The first method <b>getConnection()</b> must return an object that implements the <b>PHPUnit_Extensions_Database_DB_IDatabaseConnection</b> interface. In most cases you will return an instance of the <b>PHPUnit_Extensions_Database_DB_DefaultDatabaseConnection</b>. The constructor for this class takes two parameters. The first is a PDO object that is connected to the database you plan on using to test your functionality. The second parameter is the name of the database schema you will be testing against. I realize that <b>PHPUnit_Extensions_Database_DB_DefaultDatabaseConnection</b> is a handful to type so there is a helper method in the TestCase class that will instantiates a database connection with the same arguments: <b>createDefaultDBConnection(PDO $connection, string $schema)</b>.</p>
<p>You can choose a variety of methods to get the PDO object to pass to this method. For this example I will create the connection in the test case constructor and add it as a protected class property. For large test suites you may want to use a static singleton method of a test utility class to help get rid of some of the overhead of opening and closing connections. Here is our test case with the <b>getConnection()</b> method implemented:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">require_once 'PHPUnit/Extensions/Database/TestCase.php';<br />
<br />
class BankAccountDBTest extends PHPUnit_Extensions_Database_TestCase<br />
{<br />
&nbsp; &nbsp; protected $pdo;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; public function __construct()<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; $this-&gt;pdo = new PDO('sqlite::memory:');<br />
&nbsp; &nbsp; &nbsp; &nbsp; BankAccount::createTable($this-&gt;pdo);<br />
&nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; protected function getConnection()<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; return $this-&gt;createDefaultDBConnection($this-&gt;pdo, 'sqlite');<br />
&nbsp; &nbsp; }<br />
}</div></div>
<p>For my test I have simply chosen to use the memory database in sqlite. I have chosen this simply because it is faster than an sqlite database in the filesystem and this is just a tutorial so persistence of the file is simply not needed. I have called the <b>BankAccount::createTable()</b> method to create the schema that the <b>BankAccount </b>object uses. The downside to using the memory database is you have to create your schema every time. Normally you would have a persistant database for testing that would always have the necessary schema to test your code. Note that when using sqlite what you pass as the $schema parameter does not really matter since sqlite does not really have the concept of schemas.</p>
<p>This brings us to the next required method. The <b>getDataSet()</b> method is used to return the seed data that is used in <b>setUp()</b> and <b>tearDown() </b>operations for each test. There are currently two different ways to easily load datasets: the Flat XML DataSet and the XML DataSet. The flat XML data set is an extremely simple yet somewhat limited data set where the XML data set is slightly more complicated but much more robust when dealing with null values. For our example we will use the flat xml data set.</p>
<p>In the flat xml data set you create a root element named dataset and then create xml element for every row in every table of your database. The element name is equal to the table name the row resides in. The element will have one attribute for each column in the table. If there is an attribute missing for one element that exists in another element then that colum for the row with the missing attribute will be set to NULL. Please note that colname=&quot;&quot; will not set that column to null. It will set it to an empty string (or whatever that translates to for that articular column&#8217;s data type.</p>
<p>The flat xml data set we will be using is as follows:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;dataset&gt;<br />
&nbsp; &nbsp; &lt;bank_account account_number=&quot;15934903649620486&quot; balance=&quot;100.00&quot; /&gt;<br />
&nbsp; &nbsp; &lt;bank_account account_number=&quot;15936487230215067&quot; balance=&quot;1216.00&quot; /&gt;<br />
&nbsp; &nbsp; &lt;bank_account account_number=&quot;12348612357236185&quot; balance=&quot;89.00&quot; /&gt;<br />
&lt;/dataset&gt;</div></div>
<p>The classname of the flat xml data set is <b>PHPUnit_Extensions_Database_DataSet_FlatXMLDataSet</b> and it&#8217;s only argument is the path to xml file that you are loading. Once again, this is an astronomically long class name so there is a helper method to instantiate this class: <b>createFlatXMLDataSet()</b>.</p>
<p>Here is our test case with the <b>getDataSet()</b> method implemented:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">require_once 'PHPUnit/Extensions/Database/TestCase.php';<br />
<br />
class BankAccountDBTest extends PHPUnit_Extensions_Database_TestCase<br />
{<br />
&nbsp; &nbsp; protected $pdo;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; public function __construct()<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; $this-&gt;pdo = new PDO('sqlite::memory:');<br />
&nbsp; &nbsp; &nbsp; &nbsp; BankAccount::createTable($this-&gt;pdo);<br />
&nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; protected function getConnection()<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; return $this-&gt;createDefaultDBConnection($this-&gt;pdo, 'sqlite');<br />
&nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; protected function getDataSet()<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; return $this-&gt;createFlatXMLDataSet(dirname(__FILE__).'/_files/bank-account-seed.xml');<br />
&nbsp; &nbsp; }<br />
}</div></div>
<p>Now in a default implementation the database extension will perform a &#8216;clean insert&#8217; operation on your database using the the dataset returned by getDataSet. The clean insert operation will truncate any tables in the data set (not all tabes in the database) and then insert the rows in the dataset. The default implementation will do nothing on tear down. There are several other operations that can be used by adding the <b>getSetUpOperation() </b>and <b>getTearDownOperation() </b>methods. These methods should return a <b>PHPUnit_Extensions_Database_Operation_*</b> class. These operations can be returned using the test case&#8217;s <b>getOperations()</b> method. The default set up implementation is the equivelant of creating the following <b>getSetUpOperation()</b>.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; protected function getSetUpOperation()<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; return $this-&gt;getOperations()-&gt;CLEAN_INSERT();<br />
&nbsp; &nbsp; }</div></div>
<p>There is one more thing to take note of before we dive into our first test. The Database_Testcase is heavily dependant on it&#8217;s implementation of <b>setUp()</b> and <b>tearDown()</b> for it&#8217;s functionality to work. If you need to perform additional setup or teardown actions make sure you call the parent versions of these functions as well.</p>
<p>The functionality I would like to test in this example is testing new account creation. In the bank account class, whenever a new BankAccount class is instantiated it is supposed to create a new bank account with a zero balance in the database. To test this we will need to create another dataset representing our seed data with the expected changes.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;dataset&gt;<br />
&nbsp; &nbsp; &lt;bank_account account_number=&quot;15934903649620486&quot; balance=&quot;100.00&quot; /&gt;<br />
&nbsp; &nbsp; &lt;bank_account account_number=&quot;15936487230215067&quot; balance=&quot;1216.00&quot; /&gt;<br />
&nbsp; &nbsp; &lt;bank_account account_number=&quot;12348612357236185&quot; balance=&quot;89.00&quot; /&gt;<br />
&nbsp; &nbsp; &lt;bank_account account_number=&quot;15936487230215067&quot; balance=&quot;1216.00&quot; /&gt;<br />
&lt;/dataset&gt;</div></div>
<p>Using this data set we can create a new test that instantiates a bank account object and then we will assert that the contents of the database are equal to the dataset we just created. In order to compare the database to your dataset you need to create a dataset containing the contents of your database. This is done by calling the <b>createDataSet()</b> method of the database connection object you created in the <b>getConnection()</b> method. You can then pass it to the <b>assertDataSetsEqual()</b> function. Also notice that you can just reuse the <b>createFlatXMLDataSet()</b> method to load the expected dataset.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">require_once 'PHPUnit/Extensions/Database/TestCase.php';<br />
<br />
class BankAccountDBTest extends PHPUnit_Extensions_Database_TestCase<br />
{<br />
&nbsp; &nbsp; protected $pdo;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; public function __construct()<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; $this-&gt;pdo = new PDO('sqlite::memory:');<br />
&nbsp; &nbsp; &nbsp; &nbsp; BankAccount::createTable($this-&gt;pdo);<br />
&nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; protected function getConnection()<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; return $this-&gt;createDefaultDBConnection($this-&gt;pdo, 'sqlite');<br />
&nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; protected function getDataSet()<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; return $this-&gt;createFlatXMLDataSet(dirname(__FILE__).'/_files/bank-account-seed.xml');<br />
&nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; public function testNewAccountCreation()<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; $bank_account = new BankAccount('12345678912345678', $this-&gt;pdo);<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; $xml_dataset = $this-&gt;createFlatXMLDataSet(dirname(__FILE__).'/_files/bank-account-after-new-account.xml');<br />
&nbsp; &nbsp; &nbsp; &nbsp; $this-&gt;assertDataSetsEqual($xml_dataset, $this-&gt;getConnection()-&gt;createDataSet());<br />
&nbsp; &nbsp; }<br />
}</div></div>
<p>If you have a large database data set you can also compare at the table level using the test case method <b>assertTablesEqual()</b>. You can pass it individual tables by calling the <b>getTable($tableName)</b> method. This method exists for any of the data set classes. You can also limit tables at the database level by passing an array of table names to the <b>createDataSet()</b> method. So if your database had multiple tables the above function could have been rewritten as below to only compare at the table level.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">require_once 'PHPUnit/Extensions/Database/TestCase.php';<br />
<br />
class BankAccountDBTest extends PHPUnit_Extensions_Database_TestCase<br />
{<br />
&nbsp; &nbsp; protected $pdo;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; public function __construct()<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; $this-&gt;pdo = new PDO('sqlite::memory:');<br />
&nbsp; &nbsp; &nbsp; &nbsp; BankAccount::createTable($this-&gt;pdo);<br />
&nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; protected function getConnection()<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; return $this-&gt;createDefaultDBConnection($this-&gt;pdo, 'sqlite');<br />
&nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; protected function getDataSet()<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; return $this-&gt;createFlatXMLDataSet(dirname(__FILE__).'/_files/bank-account-seed.xml');<br />
&nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; public function testNewAccountCreation()<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; $bank_account = new BankAccount('12345678912345678', $this-&gt;pdo);<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; $xml_dataset = $this-&gt;createFlatXMLDataSet(dirname(__FILE__).'/_files/bank-account-after-new-account.xml');<br />
&nbsp; &nbsp; &nbsp; &nbsp; $this-&gt;assertTablesEqual($xml_dataset-&gt;getTable('bank_account'), $this-&gt;getConnection()-&gt;createDataSet()-&gt;getTable('bank_account'));<br />
&nbsp; &nbsp; }<br />
}</div></div>
<p>Or if you didn&#8217;t even want to bother loading tables you won&#8217;t be testing against:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">require_once 'PHPUnit/Extensions/Database/TestCase.php';<br />
<br />
class BankAccountDBTest extends PHPUnit_Extensions_Database_TestCase<br />
{<br />
&nbsp; &nbsp; protected $pdo;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; public function __construct()<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; $this-&gt;pdo = new PDO('sqlite::memory:');<br />
&nbsp; &nbsp; &nbsp; &nbsp; BankAccount::createTable($this-&gt;pdo);<br />
&nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; protected function getConnection()<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; return $this-&gt;createDefaultDBConnection($this-&gt;pdo, 'sqlite');<br />
&nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; protected function getDataSet()<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; return $this-&gt;createFlatXMLDataSet(dirname(__FILE__).'/_files/bank-account-seed.xml');<br />
&nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; public function testNewAccountCreation()<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; $bank_account = new BankAccount('12345678912345678', $this-&gt;pdo);<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; $xml_dataset = $this-&gt;createFlatXMLDataSet(dirname(__FILE__).'/_files/bank-account-after-new-account.xml');<br />
&nbsp; &nbsp; &nbsp; &nbsp; $this-&gt;assertDataSetsEqual($xml_dataset, $this-&gt;getConnection()-&gt;createDataSet(array('bank_account'));<br />
&nbsp; &nbsp; }<br />
}</div></div>
<p>Hopefully that is enough to pique your interest. As always, if you have any questions feel free to ask me.</p>
<div class="topsy_widget_data topsy_theme_blue" style="float: left;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fdigitalsandwich.com%252Farchives%252F63-phpunit-database-extension-dbunit-port.html%22%2C%20%22style%22%3A%20%22small%22%2C%20%22title%22%3A%20%22PHPUnit%20Database%20Extension%20%28DBUnit%20Port%29%22%20%7D);"></div>

]]></content:encoded>
			<wfw:commentRss>http://digitalsandwich.com/archives/63-phpunit-database-extension-dbunit-port.html/feed</wfw:commentRss>
		<slash:comments>33</slash:comments>
		</item>
		<item>
		<title>Finally used PHPUnit and I like it</title>
		<link>http://digitalsandwich.com/archives/56-finally-used-phpunit-and-i-like-it.html</link>
		<comments>http://digitalsandwich.com/archives/56-finally-used-phpunit-and-i-like-it.html#comments</comments>
		<pubDate>Mon, 22 May 2006 14:56:54 +0000</pubDate>
		<dc:creator>Mike Lively</dc:creator>
				<category><![CDATA[PHP Testing]]></category>

		<guid isPermaLink="false">http://digitalsandwich.com/?p=56</guid>
		<description><![CDATA[I have been working quite a bit lately with the cvs version PHPUnit3. I have spent alot of time in testing using SimpleTest and I have also given some time to test-more.php. However, up until just recently I had honestly &#8230; <a href="http://digitalsandwich.com/archives/56-finally-used-phpunit-and-i-like-it.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[
<p>I have been working quite a bit lately with the cvs version <a href="http://cvs.php.net/viewcvs.cgi/pear/PHPUnit2/">PHPUnit3</a>. I have spent alot of time in testing using <a href="http://www.lastcraft.com/simple_test.php">SimpleTest</a> and I have also given some time to <a href="http://shiflett.org/archive/187">test-more.php</a>. However, up until just recently I had honestly never used PHPUnit before. The big motivational factor for me (other than to try something new) was to see how the <a href="http://www.phpunit.de/pocket_guide/3.0/en/code-coverage-analysis.html">code coverage</a> feature was coming along.</p>
<p>I would have to say that after a few weeks of tinkering with it I am impressed. Now, keep in mind that I am talking about software that is still in development, so a degree of lattitude is required. The featureset of PHPUnit 3 is great. Here are a few notable features (in my mind):</p>
<ul>
<li>Mock objects</li>
<li>Code Coverage Analysis</li>
<li>Multitude of test logging options</li>
<li>Built well for testing &gt;php5 applications</li>
</ul>
<p>Using the framework is an absolute breeze and there is excellent documentation in the form of a free book (draft version) written by <a href="http://www.sebastian-bergmann.de/">Sebastian Bergmann</a> and published by O&#8217;Reilly called &quot;<a href="http://www.phpunit.de/pocket_guide/3.0/en/index.html">PHPUnit Pocket Guide.</a>&quot; The <a href="http://www.phpunit.de/apidoc/">API</a> is also documented quite nicely and serves as a good second-source for learning how to do specific things. </p>
<p>The most impressive part of this experience in my mind was how runnable the software is straight out of CVS. Most of the time when I am crazy enough to use CVS version I always seem to get my copy of the source at a point where it is very unstable and requires tweaking just to get the software to fulfill its basic requirements. PHPUnit 3 on the other hand was able to run in it&#8217;s standard mode without a flaw. The only thing that was missing that I felt I needed was html reports for the pass/fail status of the unit tests. The report templates and code was already to a point however that it was actually fairly trivial for me to make the changes to it that I thought would be needed to make it work. I have since passed those changes along to Sebastian and they have been added to CVS, so html reports are now in the cvs version as well. It felt good to be able to contribute a little bit to a very worthwhile project.</p>
<p>Sebastian has posted about the <a href="http://www.sebastian-bergmann.de/blog/archives/599-More-Work-on-Reporting-in-PHPUnit-3.html">new reporting features</a> on his blog that include some screenshots so I won&#8217;t bother to rehash over all of that. You can just go check them out on his site.</p>
<div class="topsy_widget_data topsy_theme_blue" style="float: left;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fdigitalsandwich.com%252Farchives%252F56-finally-used-phpunit-and-i-like-it.html%22%2C%20%22style%22%3A%20%22small%22%2C%20%22title%22%3A%20%22Finally%20used%20PHPUnit%20and%20I%20like%20it%22%20%7D);"></div>

]]></content:encoded>
			<wfw:commentRss>http://digitalsandwich.com/archives/56-finally-used-phpunit-and-i-like-it.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

