Eclipse Yoxos Services Downloads Blogs About
Home > Blogs >

Posts Tagged ‘clean code’

on Sep 29th, 2011Effective Mockito Part 2

As promised in the first part of the “Effective Mockito” blog series, I will concentrate on Mockito specifics in the followup posts. So, the main topic for Part 2 is Mockito’s @Mock Annotation.

When I write tests I try to follow an explicit pattern, called the build-operate-check pattern. This was described by Uncle Bob in his book “Clean Code” (Page 127, Chapter 9). The main idea behind this pattern is that you try to split your test method into three parts. The first part sets up the environment, the second executes the method you want to test and the third part verifies the expected. You can also apply this pattern with Mockito using the @Mock Annotation.

When writing tests we often reach a point where we need a second object to get an object under test to work. That’s where we can use mocks icon smile Effective Mockito Part 2 . The test code looks roughly like this:

public class SecondPartTest {
 
  @Test
  public void testSomething() {
    Strategy strategy = mock( Strategy.class );
    Something objectUnderTest = new Something( strategy );
 
    objectUnderTest.doSomething();
 
    verify( strategy ).doSomethingConcrete();
  }
 
}

As you can see we created an object of the type Something. This object needs another object of the type Strategy in its constructor and I decided to use a mock for this. After this we execute the method we want to test which is called doSomething. The doSomething method should invoke the method doSomethingConcrete on the object we passed in the constructor. As you’ve probably noticed, it’s the strategy pattern. I chose this one because it’s a perfect fit for the use of mocks. In the last step of the test we verify that the method doSomethingConcrete was invoked. Nothing special here.

It looks like a nice and clean little test to me. But, in most cases we have more than one test method in a test class. When a new test method is added, it could look like this:

public class SecondPartTest {
 
  @Test
  public void testSomething() {
    Strategy strategy = mock( Strategy.class );
    Something objectUnderTest = new Something( strategy );
 
    objectUnderTest.doSomething();
 
    verify( strategy ).doSomethingConcrete();
  }
 
  @Test
  public void testDelegateSomething() {
    Strategy strategy = mock( Strategy.class );
    Something objectUnderTest = new Something( strategy );
    when( strategy.doValidate() ).thenReturn( true );
 
    boolean isValid = objectUnderTest.validate();
 
    assertTrue( isValid );
  }
 
}

At this point our nice and clean little test is no longer as nice or clean. By adding one test method we introduced two redundant lines of code, the object instantiation and the mocking. This is a sign that we need to use fields for both the objectUnderTest and the mock, and create them in the @Before method as in this snippet:

public class SecondPartTest {
 
  Strategy strategy;
 
  Something objectUnderTest;
 
  @Before
  public void setUp() {
    strategy = mock( Strategy.class );
    objectUnderTest = new Something( strategy );
  }
 
  @Test
  public void testSomething() {
    objectUnderTest.doSomething();
 
    verify( strategy ).doSomethingConcrete();
  }
 
  @Test
  public void testDelegateSomething() {
    when( strategy.doValidate() ).thenReturn( true );
 
    boolean isValid = objectUnderTest.validate();
 
    assertTrue( isValid );
  }
 
}

This makes our test methods clean again, yippee icon smile Effective Mockito Part 2 . But I think we can do better. Mockito provides MockitoAnnotations and I’d like to use one of them in our test. It’s called @Mock (surprise).  Using this annotation we can tell a field that it is a mock.  It can look like this:

public class SecondPartTest {
 
  @Mock
  Strategy strategy;
 
  Something objectUnderTest;
 
  @Before
  public void setUp() {
    MockitoAnnotations.initMocks( this );
    objectUnderTest = new Something( strategy );
  }
 
  @Test
  public void testSomething() {
    objectUnderTest.doSomething();
 
    verify( strategy ).doSomethingConcrete();
  }
 
  @Test
  public void testDelegateSomething() {
    when( strategy.doValidate() ).thenReturn( true );
 
    boolean isValid = objectUnderTest.validate();
 
    assertTrue( isValid );
  }
 
}

This has at least one major benefit. You can see that a field is a mock at first glance without reading the setUp method. However, we didn’t save any lines in the setUp method because we need to tell Mockito to instantiate the @Mock annotated fields. This looks really ugly because we are mixing Mockito framework code with our test code. We need to find another way to instantiate the mocks. Luckily, Mockito helps out once again.

Since JUnit4 you can choose specific test runners for test classes. You probably know this because you use it in your TestSuite classes all the time. Anyway, Mockito provides a runner called MockitoJUnitRunner. Using the runner looks like this:

@RunWith( MockitoJUnitRunner.class )
public class SecondPartTest {
 
  @Mock
  Strategy strategy;
 
  Something objectUnderTest;
 
  @Before
  public void setUp() {
    objectUnderTest = new Something( strategy );
  }
 
  @Test
  public void testSomething() {
    objectUnderTest.doSomething();
 
    verify( strategy ).doSomethingConcrete();
  }
 
  @Test
  public void testDelegateSomething() {
    when( strategy.doValidate() ).thenReturn( true );
 
    boolean isValid = objectUnderTest.validate();
 
    assertTrue( isValid );
  }
 
}

As you can see we could remove the initMocks call in the setUp method and we are nice and clean again. And, that’s how you can get to a clean test using the @Mock annotation. In the next Effective Mockito installment I’ll show you how spies can be used to get to a clean test when you depend on third party libraries icon wink Effective Mockito Part 2 .

followme Effective Mockito Part 2

Read the other Effective Mockito posts:

on Nov 22nd, 2010A women’s way to clean code

A few weeks ago the news in Germany was that the average lifespan of German citizens has reached its highest level ever (Statistisches Bundesamt Deutschland).  This was good news but I was also surprised to hear that women still live longer than men. I can imagine a lot of contributing factors but maybe that’s a long discussion better done over beers. One thing that I’ve observed, that I think I can say without getting into trouble, is that some women I know, are simply smarter about their health. For example, if they develop symptoms, they’ll go more quickly to the doctor than I would (or other guys I know). Longevity led me to think about the lifetime of code, and how short that can be sometimes. And, how we often ignore symptoms of illness in code too.  This would be in the form of warnings during compile time, like in the following example, “death by internal API change”.

dbiac A womens way to clean code

With the right compiler settings, a modern IDE like Eclipse displays warnings when something isn’t right e.g. when using internal API.  By ignoring these warnings you are vulnerable to the ‘death by internal API change’ malady.  One day the owner of the API will change its internal structure. If you’re lucky you can adopt the new structure and your code will survive. But if you’re out of luck, the changes to the internal API are so drastic that you can’t repair your code and your application, built on top of internal API, is completely broken.

This death can be avoided by reacting to the symptoms. Let me explain this with the same example. Every programmer has found himself in the situation were a public API couldn’t do everything you needed.  If you’re writing code in a women’s way, you won’t ignore the symptoms.  A female would consult a doctor, in this case the creator of the API or the community around it. They would describe the symptoms, and with this kind of information the “doctor” can react by extending the public API of the framework. In this way, all symptoms (warnings) are recognized early and eliminated before the malady can take hold. It’s the same here as with people: if you consult the doctor early, the probability of illness will shrink.  So, be nice to your code…

Can you think of other examples where bad code is so easy to ‘catch’?  It would be great to hear your examples of  maladies like “death by internal API change” and hear your experiences.

© EclipseSource 2008 - 2011