{"id":2449,"date":"2008-09-22T13:37:10","date_gmt":"2008-09-22T11:37:10","guid":{"rendered":"http:\/\/blog.jteam.nl\/?p=2449"},"modified":"2008-09-22T13:37:10","modified_gmt":"2008-09-22T11:37:10","slug":"easymock-capturing-arguments-passed-to-mock-objects","status":"publish","type":"post","link":"https:\/\/trifork.nl\/blog\/easymock-capturing-arguments-passed-to-mock-objects\/","title":{"rendered":"EasyMock: capturing arguments passed to mock objects"},"content":{"rendered":"<p><a href=\"http:\/\/www.easymock.org\/\" target=\"_blank\" rel=\"noopener\">EasyMock2<\/a> is a library that provides an easy way to create on-the-fly mock objects based on interfaces. It can be used in combination with JUnit to create simple and powerful unit tests. Here&#8217;s an overview of the basic EasyMock flow, followed by a brief example that demonstrates a new feature in EasyMock 2.4: capturing arguments passed to MockObjects.<\/p>\n<h3>EasyMock2 basics<\/h3>\n<p>Lets assume we&#8217;re testing a ManagerImpl object that requires a Dao object to do some work. The manager passes a String object to the dao, and receives an Integer in return. Since we only want to test the Manager object in isolation, it seems a good idea to mock the Dao object.<\/p>\n<p>The Dao interface:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\ninterface Dao {\n   Integer poseQuestion(String question);\n}\n<\/pre>\n<p>The Manager interface + implementation:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\ninterface Manager {\n   String poseQuestion(String question);\n}\n<\/pre>\n<p>With implementation:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\nclass ManagerImpl1 implements Manager {\n   Dao dao;\n   public String poseQuestion(String question) {\n      return dao.poseQuestion(question).toString();\n   }\n   \/\/ Dao setter etc\n}\n<\/pre>\n<p>EasyMock basically does the following:<\/p>\n<ul>\n<li>Create a mock object from the Dao interface:\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">Dao mockDao = createMock(Dao.class);<\/pre>\n<\/li>\n<li>Inject the mock object where an actual implementation would have been used:\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">manager.setDao(mockDao);<\/pre>\n<\/li>\n<li>&#8220;Record&#8221; all expected method calls to this mock object, and define appropriate responses. So-called <em>argument matchers<\/em> are used to put constraints on the expected arguments passed to the Dao\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\nexpect(mockDao.poseQuestion(  \/\/ the expected call\n\tand(\t\/\/ merges the 2 matchers below\n\t   isA(String.class)),\t\/\/ value is a String?\n\t   eq(&quot;What's the meaning of life?&quot;))  \t\/\/ value equals given String?\n   .andReturn(new Integer(42))\t\/\/ define the return value for this method call\n   .once();\t\/\/ This call is expected only once.<\/pre>\n<\/li>\n<li>When all expected calls are recorded, put the mock object in &#8220;replay&#8221; mode\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">replay(mockDao);<\/pre>\n<\/li>\n<li>In replay mode, call the manager which in turn will call the mock object in its natural habitat\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">String theCorrectAnswer = manager.poseQuestion(&quot;What's the meaning of life?&quot;);<\/pre>\n<\/li>\n<li>Afterwards: verify if all expected calls to the mock object were actually made.\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">verify(mockDao)<\/pre>\n<\/li>\n<li>\n<h3>Capturing arguments<\/h3>\n<p>Now let&#8217;s say the manager in the above example does not pass the String argument directly to the Dao. Instead, it uses a Wrapper object as an argument for the dao method calls. The Wrapper object contains the String argument from the manager call, and some additional arguments only used in the Dao (e.g. for logging).<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\ninterface Dao2 {\n   Integer poseQuestion(Wrapper questionWrapper);\n}\n<\/pre>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\nclass ManagerImpl2 implements Manager {\n   Dao2 dao;\n\n   public String poseQuestion(String question) {\n      Wrapper wrapper = new Wrapper();\n      wrapper.setQuestion(question);\n      wrapper.setDate(new Date());\n      \/\/ wrapper.setMore(...)\n\n      return dao.poseQuestion(wrapper).toString();\n   }\n\n   \/\/ Dao2 setter etc\n}\n<\/pre>\n<p>To fully test this ManagerImpl2 class, we&#8217;d like to know exactly what arguments are stored in the Wrapper object when it&#8217;s passed to the dao. The <code>isA(Wrapper.class)<\/code> matcher is of no help: checking the type of the Wrapper argument is not enough in this case. We want to check the specific values inside it.<\/p>\n<p>EasyMock 2.4 offers a new feature to do just that. An additional <code>capture(Capture c)<\/code> matcher was added. This Matcher does not actually match anything, but stores the object passed to the mock object in a Capture object. Calling the <code>getValue()<\/code> on this Capture object later on will return the original argument. In this example, capturing the Wrapper object as it&#8217;s passed to the dao allows us to check whether it still contains the String that was used as an argument in the manager call.<\/p>\n<p>A complete unit test for ManagerImpl2 would contain a method that looks something like this:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">@Test\npublic void testPoseQuestion() {\n   ManagerImpl2 manager = new ManagerImpl2();\n   Dao2 mockDao = createMock(Dao2.class);\n\n   manager.setDao(mockDao);\n\n   Capture capturedArgument = new Capture();\n\n   expect(mockDao.poseQuestion(\n      and(\n         \/\/ capture the argument for later use\n         capture(capturedArgument),\n         \/\/ check if it is a Wrapper, as expected\n         isA(Wrapper.class)))\n   .andReturn(new Integer(42))\n   .once();\n\n   replay(mockDao);\n\n   \/\/ mockDao is used during manager call,\n   \/\/ the actual wrapper object is captured\n   manager.poseQuestion(&quot;What's the meaning of life?&quot;);\n\n   verify(mockDao);\n\n   \/\/ Check the captured argument: does it contain the original\n   \/\/ question, or was it modified by the manager somehow?\n   assertEquals(&quot;What's the meaning of life?&quot;,\n            ((Wrapper) capturedArgument.getValue()).getQuestion());\n}\n<\/pre>\n<p>The <code>capture<\/code> matcher allows for easy argument checking, without the necessity to implement additional mock arguments with custom equals\/hashCode methods.<\/p>\n<p>See the <a href=\"http:\/\/www.easymock.org\/EasyMock2_4_Documentation.html\" target=\"_blank\" rel=\"noopener\">EasyMock2.4 documentation<\/a> for more examples, and more useful tricks.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p><a href=\"http:\/\/www.easymock.org\/\" target=\"_blank\" rel=\"noopener\">EasyMock2<\/a> is a library that provides an easy way to create on-the-fly mock objects based on interfaces. It can be used in combination with JUnit to create simple and powerful unit tests. Here&#8217;s an overview of the basic EasyMock flow, followed by a brief example that demonstrates a new feature in EasyMock 2.4: capturing arguments passed to MockObjects.<\/p>\n","protected":false},"author":104,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"content-type":"","footnotes":""},"categories":[31,10],"tags":[119,11,135,120],"class_list":["post-2449","post","type-post","status-publish","format-standard","hentry","category-java","category-development","tag-easymock","tag-java","tag-mocking","tag-testing"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v24.4 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>EasyMock: capturing arguments passed to mock objects - Trifork Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/trifork.nl\/blog\/easymock-capturing-arguments-passed-to-mock-objects\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"EasyMock: capturing arguments passed to mock objects - Trifork Blog\" \/>\n<meta property=\"og:description\" content=\"EasyMock2 is a library that provides an easy way to create on-the-fly mock objects based on interfaces. It can be used in combination with JUnit to create simple and powerful unit tests. Here&#039;s an overview of the basic EasyMock flow, followed by a brief example that demonstrates a new feature in EasyMock 2.4: capturing arguments passed to MockObjects.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/trifork.nl\/blog\/easymock-capturing-arguments-passed-to-mock-objects\/\" \/>\n<meta property=\"og:site_name\" content=\"Trifork Blog\" \/>\n<meta property=\"article:published_time\" content=\"2008-09-22T11:37:10+00:00\" \/>\n<meta name=\"author\" content=\"Rommert de Bruijn\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Rommert de Bruijn\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/trifork.nl\/blog\/easymock-capturing-arguments-passed-to-mock-objects\/\",\"url\":\"https:\/\/trifork.nl\/blog\/easymock-capturing-arguments-passed-to-mock-objects\/\",\"name\":\"EasyMock: capturing arguments passed to mock objects - Trifork Blog\",\"isPartOf\":{\"@id\":\"https:\/\/trifork.nl\/blog\/#website\"},\"datePublished\":\"2008-09-22T11:37:10+00:00\",\"author\":{\"@id\":\"https:\/\/trifork.nl\/blog\/#\/schema\/person\/11a4af3ffea5a0c4c586f6e88e62de75\"},\"breadcrumb\":{\"@id\":\"https:\/\/trifork.nl\/blog\/easymock-capturing-arguments-passed-to-mock-objects\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/trifork.nl\/blog\/easymock-capturing-arguments-passed-to-mock-objects\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/trifork.nl\/blog\/easymock-capturing-arguments-passed-to-mock-objects\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/trifork.nl\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"EasyMock: capturing arguments passed to mock objects\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/trifork.nl\/blog\/#website\",\"url\":\"https:\/\/trifork.nl\/blog\/\",\"name\":\"Trifork Blog\",\"description\":\"Keep updated on the technical solutions Trifork is working on!\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/trifork.nl\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/trifork.nl\/blog\/#\/schema\/person\/11a4af3ffea5a0c4c586f6e88e62de75\",\"name\":\"Rommert de Bruijn\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/trifork.nl\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/34c3020d585e4cd4e7ce43d9484d8560?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/34c3020d585e4cd4e7ce43d9484d8560?s=96&d=mm&r=g\",\"caption\":\"Rommert de Bruijn\"},\"url\":\"https:\/\/trifork.nl\/blog\/author\/rommert\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"EasyMock: capturing arguments passed to mock objects - Trifork Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/trifork.nl\/blog\/easymock-capturing-arguments-passed-to-mock-objects\/","og_locale":"en_US","og_type":"article","og_title":"EasyMock: capturing arguments passed to mock objects - Trifork Blog","og_description":"EasyMock2 is a library that provides an easy way to create on-the-fly mock objects based on interfaces. It can be used in combination with JUnit to create simple and powerful unit tests. Here's an overview of the basic EasyMock flow, followed by a brief example that demonstrates a new feature in EasyMock 2.4: capturing arguments passed to MockObjects.","og_url":"https:\/\/trifork.nl\/blog\/easymock-capturing-arguments-passed-to-mock-objects\/","og_site_name":"Trifork Blog","article_published_time":"2008-09-22T11:37:10+00:00","author":"Rommert de Bruijn","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Rommert de Bruijn","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/trifork.nl\/blog\/easymock-capturing-arguments-passed-to-mock-objects\/","url":"https:\/\/trifork.nl\/blog\/easymock-capturing-arguments-passed-to-mock-objects\/","name":"EasyMock: capturing arguments passed to mock objects - Trifork Blog","isPartOf":{"@id":"https:\/\/trifork.nl\/blog\/#website"},"datePublished":"2008-09-22T11:37:10+00:00","author":{"@id":"https:\/\/trifork.nl\/blog\/#\/schema\/person\/11a4af3ffea5a0c4c586f6e88e62de75"},"breadcrumb":{"@id":"https:\/\/trifork.nl\/blog\/easymock-capturing-arguments-passed-to-mock-objects\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/trifork.nl\/blog\/easymock-capturing-arguments-passed-to-mock-objects\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/trifork.nl\/blog\/easymock-capturing-arguments-passed-to-mock-objects\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/trifork.nl\/blog\/"},{"@type":"ListItem","position":2,"name":"EasyMock: capturing arguments passed to mock objects"}]},{"@type":"WebSite","@id":"https:\/\/trifork.nl\/blog\/#website","url":"https:\/\/trifork.nl\/blog\/","name":"Trifork Blog","description":"Keep updated on the technical solutions Trifork is working on!","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/trifork.nl\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/trifork.nl\/blog\/#\/schema\/person\/11a4af3ffea5a0c4c586f6e88e62de75","name":"Rommert de Bruijn","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/trifork.nl\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/34c3020d585e4cd4e7ce43d9484d8560?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/34c3020d585e4cd4e7ce43d9484d8560?s=96&d=mm&r=g","caption":"Rommert de Bruijn"},"url":"https:\/\/trifork.nl\/blog\/author\/rommert\/"}]}},"_links":{"self":[{"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/posts\/2449","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/users\/104"}],"replies":[{"embeddable":true,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/comments?post=2449"}],"version-history":[{"count":0,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/posts\/2449\/revisions"}],"wp:attachment":[{"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/media?parent=2449"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/categories?post=2449"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/tags?post=2449"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}