{"id":61,"date":"2007-10-04T08:19:01","date_gmt":"2007-10-04T12:19:01","guid":{"rendered":"http:\/\/danielroop.com\/blog\/2007\/10\/04\/jmock-and-aspectj\/"},"modified":"2007-10-04T08:19:01","modified_gmt":"2007-10-04T12:19:01","slug":"jmock-and-aspectj","status":"publish","type":"post","link":"http:\/\/danielroop.com\/blog\/2007\/10\/04\/jmock-and-aspectj\/","title":{"rendered":"JMock and AspectJ"},"content":{"rendered":"<p>I think it is no secret that I have become obsessed with unit testing, more specifically the mockist theory of testing. Unfortunately over the last two weeks I have come across a scenario that <a href=\"http:\/\/www.jmock.org\/\">JMock<\/a> does not allow me to test very easily.<\/p>\n<p>The scenario is basically when you instantiate an object inside of a method to preform some action.  This problem is only occuring because I am not using a factory to get my objects. If I were using a factory, I could inject a mock factory and all would be wonderful.  Now we can debate back and forth whether I should use a factory or not, but at the end of the day it doesn&#8217;t matter, because this scenario will occur at some point.  Descriptions are a lot harder than code, here is what I am talking about:<\/p>\n<pre><code>\r\npublic List<Person> getPeopleHiredOn(Date hireDate)\r\n{\r\n   PersonSearch search = new PersonSearch();\r\n   return search.by(hireDate);\r\n} \r\n<\/code><\/pre>\n<p>Just for good measure I will throw in a second scenario:<\/p>\n<pre><code>\r\npublic void sendInvitationEmail(String address)\r\n{\r\n   InvitationEmail email = new InvitationEmail();\r\n   email.sendTo(address);\r\n   email.send();\r\n} \r\n<\/code><\/pre>\n<p>Going forward I am going to focus on the first example. <\/p>\n<p>I want to point out that this situation seems to occur in the service layer of my application.  The scenario is usually when I am creating a domain object to handle a request from an input to the API.  However, I am sure it can occur in other places as well.<\/p>\n<p>JMock gives you many options for manipulating your code, but it doesn&#8217;t do you any good unless there is a object you can inject at some point into the process.  In this case, I have no such object, because the object is being created within the method I want to test.  Enter <a href=\"http:\/\/eclipse.org\/aspectj\">AspectJ<\/a>.<\/p>\n<p>With AspectJ I gain the ability to intercept the creation of the PersonSearch object and replace it with a mock.  My goal is to have the final test method look like this:<\/p>\n<pre><code>\r\npublic class PersonServiceTest\r\n{\r\n...\r\n   @Test\r\n   public void shouldExecuteNewPersonSearchWithSuppliedDate()  \r\n   {\r\n      final Date hireDate = new Date();\r\n      final List results = new ArrayList();\r\n      PersonService service = new PersonService();\r\n      \r\n      mockery.checking(new Expectations(){{\r\n         one(personSearch).by(hireDate);\r\n         will(returnValue(results));\r\n      }});\r\n      \r\n      List matchingPeople =  service.getPeopleHiredOn(hireDate);\r\n\r\n      assertEqual(matchingPeople, results);\r\n   }\r\n...\r\n}\r\n<\/code><\/pre>\n<p>Assuming that you have an understanding of JMock, the only thing that should look out of place would be that I never declare or initialize personSearch.  This is where the magic comes in, I declare the personSearch as static and initialize it in a setup method.<\/p>\n<pre><code>\r\npublic class PersonServiceTest\r\n{\r\n   private Mockery mockery = new Mockery() {{setImposteriser(ClassImposteriser.INSTANCE);}};\r\n   private static PersonSearch personSearch;\r\n\r\n   @Before\r\n   public void resetMocks()\r\n   {\r\n      personSearch = mockery.mock(PersonSearch.class);\r\n   }\r\n...\r\n<\/code><\/pre>\n<p>Because I needed to extend a concrete class, I had to add the <em>setImposteriser<\/em> to the declaration of my mockery, but that isn&#8217;t really important in this example. The only unusual thing I have done is use a setup method to create my mocks instead of doing them inline and declaring them as static. I will get to the static declaration in a second.<\/p>\n<p>The next step is to create our Aspect.  In <abbr title=\"Aspect Oriented Programming\">AOP<\/abbr>, an Aspect is a collection of <a href=\"http:\/\/en.wikipedia.org\/wiki\/Pointcut\">pointcuts<\/a> and <a href=\"http:\/\/en.wikipedia.org\/wiki\/Advice_in_aspect-oriented_programming\">advise<\/a> that you want to occur in your program.  My Aspect looks like this:<\/p>\n<pre><code>\r\npublic class PersonServiceTest\r\n{\r\n...\r\n\r\n   @Aspect\r\n   static class TestAspects\r\n   {\r\n      @Pointcut(\"call(com.danielroop.personservice.PersonSearch.new(..))\")\r\n      public void interceptPersonSearchConstructor(){}\r\n\r\n      @Around(\"interceptPersonSearchConstructor()\")\r\n      public PersonSearch interceptConstructorForPersonSearch()\r\n      {\r\n         return personSearch;\r\n      }\r\n   }\r\n}\r\n<\/code><\/pre>\n<p>The first thing to note, is that I used the AspectJ 5 annotation support.  Next you should notice that I created this as a sub class of my test class.  On a side note, I attempted making the test case an Aspect but I ran into conflicts between the JUnit and AspectJ @Before and @After annotations, because apparently AspectJ doesn&#8217;t check the type of annotation, just the name.  Anyways, this is where the static personSearch is important.  In order to create a subclass Aspect like I did here, you have to make it a static class, so in order to access personSearch from the parent you must make it static.  I am not sure why the Aspect needs to be static, but the compiler told me so, so I didn&#8217;t argue.<\/p>\n<p>That is it, at this point whenever new PersonSearch() gets called any where in this test case it will replace it with a version of my mock PersonSearch, that I can then set expectations on in my test method.<\/p>\n<p>I am a little disappointed with a few of the hoops I needed to jump through, and wish that JMock incorporated Aspects into their expectations, but for now we have to make due with the tools we have.<\/p>\n<p>The final class would look like this:<\/p>\n<pre><code>\r\npublic class PersonServiceTest\r\n{\r\n   private Mockery mockery = new Mockery() {{setImposteriser(ClassImposteriser.INSTANCE);}};\r\n   private static PersonSearch personSearch;\r\n\r\n   @Before\r\n   public void resetMocks()\r\n   {\r\n      personSearch = mockery.mock(PersonSearch.class);\r\n   }\r\n\r\n   @Test\r\n   public void shouldExecuteNewPersonSearchWithSuppliedDate()  \r\n   {\r\n      final Date hireDate = new Date();\r\n      final List results = new ArrayList();\r\n      PersonService service = new PersonService();\r\n      \r\n      mockery.checking(new Expectations(){{\r\n         one(personSearch).by(hireDate);\r\n         will(returnValue(results));\r\n      }});\r\n      \r\n      List matchingPeople =  service.getPeopleHiredOn(hireDate);\r\n\r\n      assertEqual(matchingPeople, results);\r\n   }\r\n\r\n   @Aspect\r\n   static class TestAspects\r\n   {\r\n      @Pointcut(\"call(com.danielroop.personservice.PersonSearch.new(..))\")\r\n      public void interceptPersonSearchConstructor(){}\r\n\r\n      @Around(\"interceptPersonSearchConstructor()\")\r\n      public PersonSearch interceptConstructorForPersonSearch()\r\n      {\r\n         return personSearch;\r\n      }\r\n   }\r\n}\r\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>I think it is no secret that I have become obsessed with unit testing, more specifically the mockist theory of testing. Unfortunately over the last two weeks I have come across a scenario that JMock does not allow me to &hellip; <a href=\"http:\/\/danielroop.com\/blog\/2007\/10\/04\/jmock-and-aspectj\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[50],"tags":[66,65,27,64,49],"class_list":["post-61","post","type-post","status-publish","format-standard","hentry","category-testing","tag-aop","tag-aspectj","tag-java","tag-jmoc","tag-junit"],"_links":{"self":[{"href":"http:\/\/danielroop.com\/blog\/wp-json\/wp\/v2\/posts\/61","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/danielroop.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/danielroop.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/danielroop.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/danielroop.com\/blog\/wp-json\/wp\/v2\/comments?post=61"}],"version-history":[{"count":0,"href":"http:\/\/danielroop.com\/blog\/wp-json\/wp\/v2\/posts\/61\/revisions"}],"wp:attachment":[{"href":"http:\/\/danielroop.com\/blog\/wp-json\/wp\/v2\/media?parent=61"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/danielroop.com\/blog\/wp-json\/wp\/v2\/categories?post=61"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/danielroop.com\/blog\/wp-json\/wp\/v2\/tags?post=61"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}