{"id":1246,"date":"2009-11-24T08:00:43","date_gmt":"2009-11-24T13:00:43","guid":{"rendered":"http:\/\/www.ericfeminella.com\/blog\/?p=1246"},"modified":"2022-03-24T08:29:35","modified_gmt":"2022-03-24T12:29:35","slug":"guiding-design-with-behavior-verification-and-mock-objects","status":"publish","type":"post","link":"https:\/\/www.ericfeminella.com\/blog\/2009\/11\/24\/guiding-design-with-behavior-verification-and-mock-objects\/","title":{"rendered":"Guiding Design with Behavior Verification and Mock Objects"},"content":{"rendered":"<p>At some point every developer who has disciplined themselves in the ritualistic like art and science of <a href=\"http:\/\/en.wikipedia.org\/wiki\/Test-driven_development\" target=\"_blank\" rel=\"noopener\">Test Driven Development<\/a> soon discovers that the collaborators on which a class under test depend introduce an additional layer of complexity to consider when writing your tests &#8211; and designing your APIs.<\/p>\n<p>For example, consider a simple test against a class <code>Car<\/code> which has an instance of class <code>Engine<\/code>. <code>Car<\/code> implements a <code>start<\/code> method which, when invoked, calls the <code>Engine<\/code> object&#8217;s <code>run<\/code> method. The challenge here lies in testing the dependency <code>Car<\/code> has on <code>Engine<\/code>, specifically, how one verifies that an invocation of <code>Car.start<\/code> results in the <code>Engine<\/code> object&#8217;s <code>run<\/code> method being called.<\/p>\n<p>There are two ways of testing the above example of <code>Car<\/code>, which in unit testing nomenclature is called the <a href=\"http:\/\/xunitpatterns.com\/SUT.html\" target=\"_blank\" rel=\"noopener\">System Under Test<\/a> (SUT), and it&#8217;s <code>Engine<\/code> instance which is <code>Car's<\/code> <a href=\"http:\/\/xunitpatterns.com\/DOC.html\" target=\"_blank\" rel=\"noopener\">Depended-on Component<\/a> (DOC). The most common approach is to define assertions based on the state of both the SUT and it&#8217;s DOC after being exercised. This style of testing is commonly referred to as <a href=\"http:\/\/xunitpatterns.com\/State%20Verification.html\" target=\"_blank\" rel=\"noopener\">State Verification<\/a>, and is typically the approach most developers initially use when writing tests.<\/p>\n<p>Using the above Car example, a typical State Verification test would be implemented as follows:<br \/>\n<\/p>\n<pre lang=\"actionscript\">\r\npublic class CarTest {\r\n  private var _car:Car = null;\r\n\r\n  [Before]\r\n  public function setUp() : void {\r\n    _car = new Car()\r\n  }\r\n\r\n  [Test]\r\n  public function testStart() : void {\r\n    _car.start();\r\n    assertTrue( _car.isStarted() );\r\n    assertTrue( _car.engine.isRunning() );\r\n  }\r\n\r\n   [After]\r\n  public function tearDown() : void {\r\n    _car = null;\r\n  }\r\n}\r\n<\/pre>\n<p><strong><em>Figure 1<\/em><\/strong>. CarTest, State Verification.<\/p>\n<p>From a requirements perspective and therefore a testing and implementation perspective as well, the expectation of calling <code>start<\/code> on <code>Car<\/code> is that it will A.) change it&#8217;s running state to true, and B.) invoke <code>run<\/code> on it&#8217;s <code>Engine<\/code> instance. As you can see in <em>Figure 1<\/em>, in order to test the start method on <code>Car<\/code> the <code>Engine<\/code> object must also be tested. In the example, using the State Verification style of testing, <code>Car<\/code> exposes the <code>Engine<\/code> instance in order to allow the state of <code>Engine<\/code> to be verified. This has lead to a less than ideal design as it breaks encapsulation and violates <a href=\"https:\/\/www.ericfeminella.com\/blog\/?s=Principle+of+Least+Knowledge&#038;x=0&#038;y=0\" target=\"_blank\" rel=\"noopener\">Principle of Least Knowledge<\/a>. Obviously, a better design of <code>Car.isStarted<\/code> could be implemented such that it determines if it&#8217;s <code>Engine<\/code> instance is also in a running state; however, realistically, <code>Engine.run<\/code> will likely need to do more than just set its running state to true; conceivable, it could need to do much, much more. More importantly, while testing <code>Car<\/code> one should only be concerned with the state and behavior of <code>Car<\/code> &#8211; and not that of its dependencies. As such, it soon becomes apparent that what really needs to be tested with regards to <code>Engine<\/code> in <code>Car.start<\/code> is that <code>Engine.run<\/code> is invoked, and nothing more.<\/p>\n<p>With this in mind, the implementation details of <code>Engine.run<\/code> are decidedly of less concern when testing <code>Car<\/code>; in fact, a &#8220;real&#8221; concrete implementation of <code>Engine<\/code> need not even exist in order to test <code>Car<\/code>; only the contract between <code>Car<\/code> and <code>Engine<\/code> should be of concern. Therefore, State Verification alone is not sufficient for testing <code>Car.start<\/code> as, at best, this approach unnecessarily requires a real <code>Engine<\/code> implementation or, at worst, as illustrated in <em>Figure 1<\/em>, can negatively guide design as it would require exposing the DOC in order to verify its state; effectively breaking encapsulation and unnecessarily complicating implementation. To reiterate an important point: State Verification requires an implementation of <code>Engine<\/code> and, assuming <a href=\"http:\/\/www.extremeprogramming.org\/rules\/testfirst.html\" target=\"_blank\" rel=\"noopener\">Test First<\/a> is being followed (ideally, it is), the concern when testing <code>Car<\/code> should be focused exclusively on <code>Car<\/code> and it&#8217;s interactions with its DOC; not on their specific implementations. And this is where the second style of testing &#8211; <strong>Behavior Verification<\/strong> &#8211; plays an important role in TDD.<\/p>\n<p>The <a href=\"http:\/\/xunitpatterns.com\/Behavior%20Verification.html\" target=\"_blank\" rel=\"noopener\">Behavior Verification<\/a> style of testing relies on the use of <a href=\"http:\/\/www.mockobjects.com\/\" target=\"_blank\" rel=\"noopener\">Mock Objects<\/a> in order to test the expectations of an SUT; that is, that the expected methods are called on it&#8217;s DOC with the expected parameters. Behavior Verification is most useful where State Verification alone would otherwise negatively influence design by requiring the implementation of needless state if only for the purpose of providing a more convenient means of testing. For example, many times an object may not need to be stateful or the behavior of an object may not always require a change in it&#8217;s state after exercising the SUT. In such cases, Behavior Verification with Mock Objects will lead to a simpler, more cohesive design as it requires careful design considerations of the SUT and it&#8217;s interactions with its DOC. A rather natural side-effect of this is promoting the use of interfaces over implementations as well as maintaining encapsulation.<\/p>\n<p>For testing with Behavior Verification in Flex, there are numerous Mock Object frameworks available, all of which are quite good in their own right and more or less provide different implementations of the same fundamental concepts. To name just a few, in no particular order, there are <a href=\"http:\/\/asmock.sourceforge.net\/\" target=\"_blank\" rel=\"noopener\">asMock<\/a>, <a href=\"http:\/\/bitbucket.org\/loomis\/mockito-flex\/wiki\/Home\" target=\"_blank\" rel=\"noopener\">mockito-flex<\/a>, <a href=\"http:\/\/mockolate.org\/\" target=\"_blank\" rel=\"noopener\">mockolate<\/a> and <a href=\"http:\/\/code.google.com\/p\/mock4as\/\" target=\"_blank\" rel=\"noopener\">mock4as<\/a>.<\/p>\n<p>While any of the above Mock Testing Frameworks will do, for the sake of simplicity I will demonstrate re-writing the <code>Car<\/code>test using Behavior Verification based on mock4as &#8211; if for nothing other than the fact that it requires implementing the actual Mock, which helps illustrate how everything comes together. Moreover, the goal of this essay is to help developers understand the design concepts surrounding TDD with Behavior Verification and Mock Objects by focusing on the basic design concepts; not the implementation specifics of any individual Mock Framework.<\/p>\n<p><\/p>\n<pre lang=\"actionscript\">\r\npublic class CarTest {\r\n    private var _car:Car = null;\r\n    private var _mock:MockEngine = null;\r\n\r\n    [Before]\r\n    public function setUp() : void {\r\n      _mock = new MockEngine();\r\n      _car  = new Car( _mock );\r\n    }\r\n\r\n    [Test]\r\n    public function testStartChangesState() : void {\r\n      _car.start();\r\n      assertTrue( _car.isRunning() );\r\n    }\r\n\r\n    [Test]\r\n    public function testStartInvokesEngineRun() : void {\r\n      _mock.expects( \"run\" );\r\n      _car.start();\r\n      assertTrue(_mock.errorMessage(), \r\n      _mock.success());\r\n    }\r\n\r\n    [After]\r\n    public function tearDown() : void {\r\n      _mock = null;\r\n      _car  = null;\r\n    }\r\n}\r\n<\/pre>\n<p><strong><em>Figure 2<\/em><\/strong>. CarTest, Behavior Verification approach.<\/p>\n<p>Let&#8217;s go through what has changed in <code>CarTest<\/code> now that it leverages Behavior Verification. First, <code>Car's<\/code> constructor has been refactored to require an <code>Engine<\/code> object, which now implements an <code>IEngine<\/code> interface, which is defined as follows.<\/p>\n<pre lang=\"actionscript\">\r\npublic interface IEngine {\r\n  function run() : void;\r\n}\r\n<\/pre>\n<p><strong><em>Figure 3<\/em><\/strong>. IEngine interface.<\/p>\n<p>Note <code>Engine.isRunning<\/code> is no longer tested, or even defined as, it is simply not needed when testing <code>Car<\/code>: only the call to <code>Engine.run<\/code> is to be verified in the context of calling <code>Car.start<\/code>. Since focus is exclusively on the SUT, only the interactions between <code>Car<\/code> and <code>Engine<\/code> are of importance and should be defined. The goal is to focus on the testing of the SUT and not be distracted with design or implementation details of it&#8217;s DOC outside of that which is needed by the SUT.<\/p>\n<p><code>MockEngine<\/code> provides the actual implementation of <code>IEngine<\/code>, and, as you may have guessed, is the actual Mock object implementation of <code>IEngine<\/code>. <code>MockEngine<\/code> simply serves to provide a means of verifing that when <code>Car.start<\/code> is exercised it successfully invokes <code>Engine.run<\/code>; effectively satisfiying the contract between <code>Car<\/code> and <code>Engine<\/code>. <code>MockEngine<\/code> is implemented as follows:<\/p>\n<pre lang=\"actionscript\">\r\nimport org.mock4as.Mock;\r\n\r\npublic class MockEngine extends Mock implements IEngine {\r\n  public function run() : void {\r\n    record( \"run\" );\r\n  }\r\n}\r\n<\/pre>\n<p><strong><em>Figure 4<\/em><\/strong>. MockEngine implementation.<\/p>\n<p><code>MockEngine<\/code> extends <code>org.mock4as.Mock<\/code> from which it inherits all of the functionality needed to &#8220;Mock&#8221; an object, in this case, an <code>IEngine<\/code> implementation. You&#8217;ll notice that <code>MockEngine.run<\/code> does not implement any &#8220;real&#8221; functionality, but rather it simply invokes the inherited <code>record<\/code> method, passing in the method name to record for verification when called. This is the mechanism which allows a <code>MockEngine<\/code> instance to be verified once <code>run<\/code> is invoked.<\/p>\n<p><code>CarTest<\/code> has been refactored to now provide two distinct tests against <code>Car.start<\/code>. The first, <code>testStartChangesState()<\/code>, provides the State Verification test of <code>Car<\/code>; which tests the expected state of <code>Car<\/code> after being exercised. The second test, <code>testStartInvokesEngineRun()<\/code>, provides the actual Behavior Verification test which defines the expectations of the SUT and verification of those expectations on the DOC; that is, Behavior Verification tests are implemented such that they first define expectations, then exercise the SUT, and finally, verify that the expectations have been met. In effect, this verifies that the contract between an SUT and its DOC has been satisfied.<\/p>\n<p>Breaking down the <code>testStartInvokesEngineRun()<\/code> test, it is quite easy to follow the steps used when writing a Behavior Verification test.<\/p>\n<pre lang=\"actionscript\">\r\n[Test]\r\npublic function testStartInvokesEngineStart() : void {\r\n   \/\/ Set expectations on the mock; essentially, what\r\n   \/\/ method the SUT is expected to invoke on it's DOC\r\n   _mock.expects( \"run\" );\r\n\r\n  \/ \/ Exercise the SUT\r\n   _car.start();\r\n      \r\n  \/\/ Verify expectations have been met\r\n  assertTrue(_mock.errorMessage(), mock.success());\r\n}\r\n<\/pre>\n<p>And that&#8217;s basically it. While much more can be accomplished with the many Mock Testing frameworks available for Flex, and plenty of information is available on the specifics of the subject, this essay quite necessarily aims to focus on the design benefits of testing with Behavior Verification; that is, the design considerations one must make while doing so. <\/p>\n<p>With Behavior Verification and Mock Objects, design can be guided into existence based on necessity rather than pushed into existence based on implementation.<\/p>\n<p>The example can be downloaded <a href=\"http:\/\/code.ericfeminella.com\/downloads\/MockObjectsExample.fxp\" target=\"_blank\" rel=\"noopener\">here<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>At some point every developer who has disciplined themselves in the ritualistic like art and science of Test Driven Development soon discovers that the collaborators on which a class under test depend introduce an additional layer of complexity to consider when writing your tests &#8211; and designing your APIs. For example, consider a simple test against a class Car which&#8230; <a class=\"read-more\" href=\"https:\/\/www.ericfeminella.com\/blog\/2009\/11\/24\/guiding-design-with-behavior-verification-and-mock-objects\/\">Continue Reading<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false}}},"categories":[44,23,31,45,35,40],"tags":[],"class_list":["post-1246","post","type-post","status-publish","format-standard","hentry","category-code-review","category-design-patterns","category-oop","category-refactoring","category-software-engineering","category-test-driven-development"],"jetpack_publicize_connections":[],"aioseo_notices":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.ericfeminella.com\/blog\/wp-json\/wp\/v2\/posts\/1246","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.ericfeminella.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.ericfeminella.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.ericfeminella.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ericfeminella.com\/blog\/wp-json\/wp\/v2\/comments?post=1246"}],"version-history":[{"count":0,"href":"https:\/\/www.ericfeminella.com\/blog\/wp-json\/wp\/v2\/posts\/1246\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.ericfeminella.com\/blog\/wp-json\/wp\/v2\/media?parent=1246"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.ericfeminella.com\/blog\/wp-json\/wp\/v2\/categories?post=1246"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.ericfeminella.com\/blog\/wp-json\/wp\/v2\/tags?post=1246"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}