{"id":155,"date":"2012-11-10T21:56:42","date_gmt":"2012-11-10T20:56:42","guid":{"rendered":"http:\/\/benjiweber.co.uk\/blog\/?p=155"},"modified":"2012-11-10T21:56:42","modified_gmt":"2012-11-10T20:56:42","slug":"test-stubbing-with-builders-real-objects-and-caches","status":"publish","type":"post","link":"https:\/\/benjiweber.co.uk\/blog\/2012\/11\/10\/test-stubbing-with-builders-real-objects-and-caches\/","title":{"rendered":"Test Stubbing with Builders, Real Objects, and Caches"},"content":{"rendered":"<p class=\"lead\">I thought I&#8217;d start posting some of my notes on tips for testing. Starting with some tips and tricks for <a href=\"http:\/\/code.google.com\/p\/mockito\/\">Mockito<\/a>.<\/p>\n<p>Mocking\/Stubbing frameworks like Mockito help to test units of code in isolation with minimal boilerplate.<\/p>\n<p>A couple of guidelines I like to aim to follow when writing tests are:<\/p>\n<ul>\n<li>Each test should assert\/verify just one thing (or as few things as possible)<\/li>\n<li>Minimise stubbing noise per test<\/li>\n<\/ul>\n<p>Sometimes it can be hard to write consise tests for consise, readable code. It&#8217;s often tempting to compromise the simplicity of the code under test in order to make the tests easier. However, Mockito is flexible enough that this can usually be avoided.<\/p>\n<p>Obviously we have to be careful. Often (perhaps even usually) code being hard to test is a smell, and it&#8217;s better to re-think how the code is written to make it more naturally testable.<\/p>\n<p>Here are three things that can make tests more difficult:<\/p>\n<ul>\n<li>Use of the Builder Pattern<\/li>\n<li>Use of Real Objects (not everything is stubbed)<\/li>\n<li>Methods that return arguments (e.g. put on caches)<\/li>\n<\/ul>\n<h3>Use of the Builder Pattern<\/h3>\n<p>Here&#8217;s the first example. We&#8217;d like to write some code like the following.<\/p>\n<pre lang=\"java\">public class Example1 {\r\n\tFoxBuilder foxBuilder;\r\n\tDog dog;\r\n\r\n\tpublic void someMethod() {\r\n\t\tFox fox = foxBuilder\r\n\t\t\t.speed(QUICK)\r\n\t\t\t.colour(BROWN)\r\n\t\t\t.legs(4)\r\n\t\t\t.longTail()\r\n\t\t\t.gender(MALE)\r\n\t\t\t.build();\r\n\r\n\t\tfox.jumpOver(dog);\r\n\t}\r\n}<\/pre>\n<p>If you have a basic familiarity with Mockito you might be tempted to write a test like the following. Unfortunately here<\/p>\n<ul>\n<li>The stubbing is very verbose (and could be worse in a less trivial example)<\/li>\n<li>We are testing several things in a single test, so lots of different things could break it<\/li>\n<\/ul>\n<pre lang=\"java\">@RunWith(MockitoJUnitRunner.class)\r\npublic class Example1NaiveTest {\r\n\t@Mock FoxBuilder foxBuilder;\r\n\t@Mock Fox fox;\r\n\t@Mock Dog dog;\r\n\r\n\t@InjectMocks\r\n\tExample1 example = new Example1();\r\n\r\n\t@Test public void naiveTest() {\r\n\t\twhen(foxBuilder.speed(QUICK)).thenReturn(foxBuilder);\t\r\n\t\twhen(foxBuilder.colour(BROWN)).thenReturn(foxBuilder);\r\n\t\twhen(foxBuilder.legs(4)).thenReturn(foxBuilder);\r\n\t\twhen(foxBuilder.longTail()).thenReturn(foxBuilder);\r\n\t\twhen(foxBuilder.gender(MALE)).thenReturn(foxBuilder);\r\n\t\twhen(foxBuilder.build()).thenReturn(fox);\r\n\r\n\t\texample.someMethod();\r\n\r\n\t\tverify(fox).jumpOver(dog);\r\n\t}\r\n}<\/pre>\n<p>Omitting one of the when() stubbings from the above test will result in a NullPointerException.<\/p>\n<p>Fortunately Mockito has a solution. When a method invocation on a mock has not been stubbed in the test, Mockito will fall back to the &#8220;default answer&#8221;. We can also specify what the default answer will be. So let&#8217;s create a default answer suitable for builders.<\/p>\n<p>Here we create an Answer to make Mocks return themselves from any method invocation on them that has a compatible return type.<\/p>\n<pre lang=\"java\">\r\npublic class Return {\r\n\tpublic static Answer<?> Self = new Answer<Object>() {\r\n\t\tpublic Object answer(InvocationOnMock invocation) throws Throwable {\r\n\t\t\tif (invocation.getMethod().getReturnType().isAssignableFrom(invocation.getMock().getClass())) {\r\n\t\t\t\treturn invocation.getMock();\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\treturn null;\r\n\t\t}\r\n\t};\r\n}\r\n<\/pre>\n<p>Now our test can look like this. We only have to stub out the build invocation. Notice the instantiations of the Mocks now tell Mockito to use our new default Answer.<\/p>\n<pre lang=\"java\">@RunWith(MockitoJUnitRunner.class)\r\npublic class Example1Test {\r\n\tFoxBuilder foxBuilder = mock(FoxBuilder.class, Return.Self);\r\n\tFoxBuilder quickFoxBuilder = mock(FoxBuilder.class, Return.Self);\r\n\r\n\t@Mock Fox fox;\r\n\t@Mock Dog dog;\r\n\r\n\t@InjectMocks\r\n\tExample1 example = new Example1();\r\n\r\n\t@Test public void whenSomeMethodCalled_aFox_shouldJumpOverTheLazyDog() {\r\n\t\twhen(foxBuilder.build()).thenReturn(fox);\r\n\t\texample.someMethod();\r\n\t\tverify(fox).jumpOver(dog);\r\n\t}\r\n}<\/pre>\n<p>&#8220;Ah&#8221;, you might say. &#8220;Now we&#8217;re no longer checking we build a fox of the right type&#8221;. Well, if that&#8217;s important to us we can put it in another test. That way we stick to one test per item of behaviour we want to assert.<\/p>\n<p>We can assert that the speed method on the builder is called<\/p>\n<pre lang=\"java\">@Test public void whenSomeMethodCalled_shouldCreateQuickFox() {\r\n\twhen(foxBuilder.build()).thenReturn(fox);\r\n\texample.someMethod();\r\n\tverify(foxBuilder).speed(QUICK);\r\n}<\/pre>\n<p>Or, to more properly check that the dog is jumped over by a fox-that-is-quick we could utilise two builders to represent a state transition:<\/p>\n<pre lang=\"java\">@Test public void whenSomeMethodCalled_shouldJumpOverAFoxThatIsQuick() {\r\n\twhen(foxBuilder.speed(QUICK)).thenReturn(quickFoxBuilder);\r\n\twhen(quickFoxBuilder.build()).thenReturn(fox);\r\n\texample.someMethod();\r\n\tverify(fox).jumpOver(dog);\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<h3>Real Objects<\/h3>\n<p>Now, suppose we decided that the dog should be instantiated within the method instead of a field on Example. Making it hard to test.<\/p>\n<p>Here is the code we want to write<\/p>\n<pre lang=\"java\">public class Example2 {\r\n\tFoxBuilder foxBuilder;\r\n\r\n\tpublic void someMethod() {\r\n\t\tFox fox = foxBuilder\r\n\t\t\t.speed(QUICK)\r\n\t\t\t.colour(BROWN)\r\n\t\t\t.legs(4)\r\n\t\t\t.longTail()\r\n\t\t\t.gender(MALE)\r\n\t\t\t.build();\r\n\r\n\t\tDog dog = new Dog();\r\n\r\n\t\tdog.setLazy();\r\n\r\n\t\tfox.jumpOver(dog);\r\n\t}\r\n}<\/pre>\n<p>We could create a dogFactory and stub out the creation of the dog. However, this adds complexity and changes the implementation for the test.<br \/>\nWe could use powermock to mock the Dog&#8217;s constructor.<br \/>\nHowever, there can be valid reasons not to mock objects like this. For example it&#8217;s good to avoid mocking Value Objects.<\/p>\n<p>So, how can we test it with a real object? Use a Mockito utility called an <a href=\"http:\/\/docs.mockito.googlecode.com\/hg\/org\/mockito\/ArgumentCaptor.html\">ArgumentCaptor<\/a><\/p>\n<p>Here we capture the real Dog object passed to the Fox mock, and can perform assertions on it afterwards.<\/p>\n<pre lang=\"java\">@Test public void whenSomeMethodCalled_aRealFox_shouldJumpOverTheLazyDog() {\r\n\twhen(foxBuilder.build()).thenReturn(fox);\r\n\texample.someMethod();\r\n\r\n\tArgumentCaptor dogCaptor = ArgumentCaptor.forClass(Dog.class);\r\n\tverify(fox).jumpOver(dogCaptor.capture());\r\n\tassertTrue(dogCaptor.getValue().isLazy());\t\t\r\n}<\/pre>\n<h3>Methods that Return Arguments<\/h3>\n<p>&nbsp;<\/p>\n<p>Now let&#8217;s make it harder again. Suppose the real dog passes through another object such as a cache that we&#8217;d like to stub.<\/p>\n<pre lang=\"java\">public class Example3 {\r\n\tFoxBuilder foxBuilder;\r\n\tCache cache;\r\n\r\n\tpublic void someMethod() {\r\n\t\tFox fox = foxBuilder\r\n\t\t\t.speed(QUICK)\r\n\t\t\t.colour(BROWN)\r\n\t\t\t.legs(4)\r\n\t\t\t.longTail()\r\n\t\t\t.gender(MALE)\r\n\t\t\t.build();\r\n\r\n\t\tDog dog = new Dog();\r\n\t\tdog.setLazy();\r\n\r\n\t\tdog = cache.put(dog);\r\n\r\n\t\tfox.jumpOver(dog);\r\n\t}\r\n}<\/pre>\n<p>These presents some challenges to test if we have stubbed the cache. One approach would be to test both the dog being lazy and the cache-addition in the same test, re-using the ArgumentCaptor used above.<\/p>\n<p>This is undesirable because there are two things being asserted in a single test.<\/p>\n<pre lang=\"java\">@RunWith(MockitoJUnitRunner.class)\r\npublic class Example3Test {\r\n\tFoxBuilder foxBuilder = mock(FoxBuilder.class, Return.Self);\r\n\tFoxBuilder quickFoxBuilder = mock(FoxBuilder.class, Return.Self);\r\n\r\n\t@Mock\r\n\tCache mockCache;\r\n\t@Mock\r\n\tFox fox;\r\n\t@Mock \r\n\tDog dog;\r\n\r\n\t@InjectMocks\r\n\tExample3 example = new Example3();\r\n\r\n\t@Test public void bad_whenSomeMethodCalled_aRealFox_shouldJumpOverTheLazyDog() {\r\n\t\twhen(foxBuilder.build()).thenReturn(fox);\r\n\t\twhen(mockCache.put(any(Dog.class))).thenReturn(dog);\r\n\r\n\t\texample.someMethod();\r\n\r\n\t\tArgumentCaptor dogCaptor = ArgumentCaptor.forClass(Dog.class);\r\n\t\tverify(mockCache).put(dogCaptor.capture());\r\n\t\tassertTrue(dogCaptor.getValue().isLazy());\r\n\r\n\t\tverify(fox).jumpOver(dog);\r\n\t}\r\n}<\/pre>\n<p>The trick is to use a Mockito Answer again to create a custom stubbing rule. Here we define an Answer that will return an argument passed to the mock method invocation.<\/p>\n<pre lang=\"java\">public static <T> Answer<T> argument(final int num) {\r\n\treturn new Answer<T>() {\r\n\t\t@SuppressWarnings(\"unchecked\")\r\n\t\tpublic T answer(InvocationOnMock invocation) throws Throwable {\r\n\t\t\treturn (T) invocation.getArguments()[num - 1];\r\n\t\t}\r\n\t};\r\n}<\/pre>\n<p>Using this, the test is only one line longer than it was before adding the cache. We could even move the cache stubbing (2nd line of test) to an @Before section to further declutter the test (as it&#8217;s generic cache behaviour)<\/p>\n<pre lang=\"java\">@Test public void whenSomeMethodCalled_aRealFox_shouldJumpOverTheLazyDog() {\r\n\twhen(foxBuilder.build()).thenReturn(fox);\r\n\twhen(mockCache.put(any())).thenAnswer(argument(1));\r\n\r\n\texample.someMethod();\r\n\tArgumentCaptor dogCaptor = ArgumentCaptor.forClass(Dog.class);\r\n\r\n\tverify(fox).jumpOver(dogCaptor.capture());\r\n\tassertTrue(dogCaptor.getValue().isLazy());\r\n}<\/pre>\n<p>If we actually want to assert the caching happens we can write another test. This test is consise and if it fails we will know why.<\/p>\n<p>If we cared about the specific properties of the dog being cached we could add the ArgumentCaptor back in.<\/p>\n<pre lang=\"java\">@Test public void whenSomeMethodCalled_aFoxShouldBeCached() {\r\n\twhen(foxBuilder.build()).thenReturn(fox);\r\n\texample.someMethod();\r\n\tverify(mockCache).put(any(Dog.class));\r\n}<\/pre>\n<p><a href=\"https:\/\/github.com\/benjiman\/test-examples\/\">The examples used in this post are on github<\/a><\/p>\n<p>There are lots of other things you can use Mockito Answers for. Take a look at the Answers enum for some of the default answers provided. <a href=\"http:\/\/docs.mockito.googlecode.com\/hg\/org\/mockito\/Mockito.html#RETURNS_DEEP_STUBS\">RETURN_DEEP_STUBS<\/a> can be useful, particularly for testing legacy code.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I thought I&#8217;d start posting some of my notes on tips for testing. Starting with some tips and tricks for Mockito. Mocking\/Stubbing frameworks like Mockito help to test units of code in isolation with minimal boilerplate. A couple of guidelines I like to aim to follow when writing tests are: Each test should assert\/verify just&#8230;  <a href=\"https:\/\/benjiweber.co.uk\/blog\/2012\/11\/10\/test-stubbing-with-builders-real-objects-and-caches\/\" class=\"more-link\" title=\"Read Test Stubbing with Builders, Real Objects, and Caches\">Read more &raquo;<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v14.9 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/benjiweber.co.uk\/blog\/2012\/11\/10\/test-stubbing-with-builders-real-objects-and-caches\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Test Stubbing with Builders, Real Objects, and Caches - Benji&#039;s Blog\" \/>\n<meta property=\"og:description\" content=\"I thought I&#8217;d start posting some of my notes on tips for testing. Starting with some tips and tricks for Mockito. Mocking\/Stubbing frameworks like Mockito help to test units of code in isolation with minimal boilerplate. A couple of guidelines I like to aim to follow when writing tests are: Each test should assert\/verify just... Read more &raquo;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/benjiweber.co.uk\/blog\/2012\/11\/10\/test-stubbing-with-builders-real-objects-and-caches\/\" \/>\n<meta property=\"og:site_name\" content=\"Benji&#039;s Blog\" \/>\n<meta property=\"article:published_time\" content=\"2012-11-10T20:56:42+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebSite\",\"@id\":\"https:\/\/benjiweber.co.uk\/blog\/#website\",\"url\":\"https:\/\/benjiweber.co.uk\/blog\/\",\"name\":\"Benji&#039;s Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":\"https:\/\/benjiweber.co.uk\/blog\/?s={search_term_string}\",\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/benjiweber.co.uk\/blog\/2012\/11\/10\/test-stubbing-with-builders-real-objects-and-caches\/#webpage\",\"url\":\"https:\/\/benjiweber.co.uk\/blog\/2012\/11\/10\/test-stubbing-with-builders-real-objects-and-caches\/\",\"name\":\"Test Stubbing with Builders, Real Objects, and Caches - Benji&#039;s Blog\",\"isPartOf\":{\"@id\":\"https:\/\/benjiweber.co.uk\/blog\/#website\"},\"datePublished\":\"2012-11-10T20:56:42+00:00\",\"dateModified\":\"2012-11-10T20:56:42+00:00\",\"author\":{\"@id\":\"https:\/\/benjiweber.co.uk\/blog\/#\/schema\/person\/45ecb36b51f4ce99e6929d2d31ca5c09\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/benjiweber.co.uk\/blog\/2012\/11\/10\/test-stubbing-with-builders-real-objects-and-caches\/\"]}]},{\"@type\":\"Person\",\"@id\":\"https:\/\/benjiweber.co.uk\/blog\/#\/schema\/person\/45ecb36b51f4ce99e6929d2d31ca5c09\",\"name\":\"benji\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/benjiweber.co.uk\/blog\/#personlogo\",\"inLanguage\":\"en-US\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/05fb47b31a0b329e1b790074a9b624ef?s=96&d=mm&r=g\",\"caption\":\"benji\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","amp_enabled":true,"_links":{"self":[{"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/posts\/155"}],"collection":[{"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/comments?post=155"}],"version-history":[{"count":22,"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/posts\/155\/revisions"}],"predecessor-version":[{"id":177,"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/posts\/155\/revisions\/177"}],"wp:attachment":[{"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/media?parent=155"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/categories?post=155"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/tags?post=155"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}