Monday, 12 August 2013

Enums and interfaces? Interesting connection

We often have to make a decision based on enum value. Usually it ends in long switch statement. What if I told you there is a better way to do this?

1. What do we want?


We want our enum to be self-describing and to achive this we created interface:

1
2
3
public interface SelfDescribing {
 String getDescription();
}


2. What do we have?


1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
public enum MessageType implements SelfDescribing {
 INFO, WARNING, ERROR;

 public String getDescription() {
  switch (this) {
  case ERROR:
   return "What do you want? Go fix your problem.";
  case INFO:
   return "Hi i'm INFO Message";
  case WARNING:
   return "Hi i'm WARNING Message";
  default:
   return null;
  }
 }
}


What we see here is switch statement. It's just ugly and after you add new message type you will have to remember about extending it. Compiler won't remind you about it.

3. What is more elegant solution?


1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
public enum MessageType implements SelfDescribing{
 INFO
 {
  public String getDescription() {
   return "Hi i'm INFO Message";
  }
  
 }, WARNING
 {
  public String getDescription() {
   return "Hi i'm WARNING Message";
  }
 }, ERROR
 {
  public String getDescription() {
   return "What do you want? Go fix your problem.";
  }
 };
}


It's cleaner, more focused on goal and less error-prone.

Monday, 5 August 2013

Why do we need Mockito?

It's impossible to create huge project without using unit tests. It seems that their popularity started with xUnit libraries family. Possibility to write hundreds of unit tests and ease of understanding results ("green bar") change the way we're programming. But what if we can't  test our class using only JUnit?


1. Let's define the problem

Consider situation when our class is using other object method but due to some reasons we can't use that object in unit test.

1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
public final class Publisher {
 private final PlagiarismChecker plagiarismChecker;

 public Publisher(PlagiarismChecker plagiarismChecker) {
  this.plagiarismChecker = plagiarismChecker;
 }

 public void publishNewNovel(Writer writer) throws Plagiarism {
  Novel novel = writer.getNovel();
  plagiarismChecker.check(novel);
  publish(novel);
 }

 private void publish(Novel novel) { 
 }
}
1
2
3
public interface PlagiarismChecker {
 void check(Novel novel) throws Plagiarism;
}

Our publisher wants to publish new novel. Unfortunately during tests we cannot check if novel is plagiarism. This operation is very long and needs access to database. For these reasons we cannot use default PlagiarismChecker implementation in test environment.

2. Solution

2.1 Prerequisites

Firstly we have to design our class to use some kind of dependency injection. I don't order you to use Spring or Guice. My point is to destroy tight-coupling between classes. We have to have possibility to change object dependences.

2.2 Possible solutions

When we gain possibility to change object dependences we have to decide what to inject. There are three basic approaches. We can use:

  • Stubs - they are the simplest implementation of some interface. We usually return hard-coded values.
    Dilbert's comics is great example.
  • Fakes - they are more advanced then Stubs. They offering some basic functionalities, but they are operating in simplified way. In our example PlagiarismChecker could compare novel title with some existing list.
  • Mocks - helps with assertions. Can return hard-coded and calculated values. They are usually created by third-parties libraries. 
We are going to try mocks using Mockito.

2.3 Adding Mockito to project

We have to add dependency to w pom.xml (i assume we are using Maven).

1
2
3
4
5
<dependency>
 <groupId>org.mockito</groupId>
 <artifactId>mockito-all</artifactId>
 <version>1.9.5</version>
</dependency>

That's all. Now we can use Mockito. In particular we can create mocks.

 2.4 First mock

1
2
PlagiarismChecker plagiarismCheckerMock = mock(PlagiarismChecker.class);
when(plagiarismCheckerMock.check(Matchers.any(Novel.class))).thenReturn(false);

This two lines have created fully "functional" PlagiarismChecker object. When w invoke method check (for any Novel) we will get false. Short explanation:
  1. We used static Mockito function when. Mockito library was designed to be  easy to read and understand. Consider when as begining of the sentence.
  2. We are passing argument to when method. In this case it is call to method check of plagiarismCheckerMock. To specify call arguments we are using Matchers.
  3. Finally we are saying what is going to happen after our call.
2.5 Final test

1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import org.junit.Test;
import org.mockito.Matchers;

public final class PublisherTest {

 @Test
 public void testGetNovel() throws Plagiarism {
  PlagiarismChecker plagiarismCheckerMock = mock(PlagiarismChecker.class);
  when(plagiarismCheckerMock.check(Matchers.any(Novel.class)))
    .thenReturn(false);

  Writer writerMock = mock(Writer.class);
  when(writerMock.getNovel()).thenReturn(new Novel());

  Publisher publisher = new Publisher(plagiarismCheckerMock);
  publisher.publishNewNovel(writerMock);
 }
}

What's important we are not testing Writer and PlagiarismChecker. Out test if fully independent.

3. Summary

I showed the simplest usage of Mockito. You need to remember that it's very powerful library. It offers: counting methods call, throwing exceptions, diffrent method results for diffrent parameters and many others.