Thursday, October 21, 2010
Friday, October 8, 2010
Mockito Sample
I am one of those Developers who "steals" the code from the web. But in this case I write my own example, because I have been told so...
Mockito is a mock object framework for Java. You can find it here. The following example shows how to mock up the dependencies for your system under JUnit test. In this particular example, I'm testing an InventoryService class and it has a dependency to a BookDao interface. Using interface-based programming makes it easy to swap in different implementations of a supertype. First we have object Book - simple POJO:
Second, the interface types for BookInventoryService
and BookDao:
Next up is the implementation of BookInventory - MysteryBookInventory class, which will be tested.
The MysteryBookInventory collaborates with a BookDao type, but it does not take on the responsibility of creating the BookDao implementation. That responsibility lies elsewhere in the application. In this scenario, the unit test will provide the implementation (a mock implementation using Mockito) and inject that instance into the MysteryBookInventory instance.
Finally the unit tests. Mockito is used to create mock instances of the BookDao type, suitable for testing the BookInventoryService implementation. I am using @Mock Annotation. You can import it through RunWith JUnit statement or you will have to import it as a package at the beginning. I have 3 tests set up: 1) verification of a state and of a method call; 2) verifying the Exception thrown and 3) is consecutive stubbing:
Mockito is a mock object framework for Java. You can find it here. The following example shows how to mock up the dependencies for your system under JUnit test. In this particular example, I'm testing an InventoryService class and it has a dependency to a BookDao interface. Using interface-based programming makes it easy to swap in different implementations of a supertype. First we have object Book - simple POJO:
package example1.model;
public class Book {
private int id;
private String name;
private String author;
private int year;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public void setYear(int year) {
this.year = year;
}
public int getYear() {
return year;
}
}
Second, the interface types for BookInventoryService
package example1.service;
import java.util.List;
import example1.dao.BookDao;
import example1.model.Book;
public interface BookInventoryService {
public void setDataAccess(BookDao bookDao);
public List<Book> getInventory();
public Book getInventoryById(int id) throws Exception;
public void updateInventory(List<Book> books);
public void deleteInventory(List<Book> books);
}
and BookDao:
package example1.dao;
import java.util.List;
import example1.model.Book;
public interface BookDao {
public Book getBookById(int id);
public List <Book> getBooks();
public void updateBook(Book book);
public void deleteBook(Book book);
}
Next up is the implementation of BookInventory - MysteryBookInventory class, which will be tested.
The MysteryBookInventory collaborates with a BookDao type, but it does not take on the responsibility of creating the BookDao implementation. That responsibility lies elsewhere in the application. In this scenario, the unit test will provide the implementation (a mock implementation using Mockito) and inject that instance into the MysteryBookInventory instance.
package example1.service;
import java.util.List;
import example1.dao.BookDao;
import example1.model.Book;
public class MysteryBookInventoryService implements BookInventoryService{
BookDao bookDao;
@Override
public void setDataAccess(BookDao bookDao) {
this.bookDao = bookDao;
}
@Override
public List<Book> getInventory() {
return bookDao.getBooks();
}
@Override
public Book getInventoryById(int id) throws Exception {
Book book = bookDao.getBookById(id);
if (book == null) {
throw new Exception("Book not found.");
}
return book;
}
@Override
public void updateInventory(List<Book> books) {
for (Book book : books) {
bookDao.updateBook(book);
}
}
@Override
public void deleteInventory(List<Book> books) {
for (Object book : books) {
bookDao.deleteBook((Book)book);
}
}
}
Finally the unit tests. Mockito is used to create mock instances of the BookDao type, suitable for testing the BookInventoryService implementation. I am using @Mock Annotation. You can import it through RunWith JUnit statement or you will have to import it as a package at the beginning. I have 3 tests set up: 1) verification of a state and of a method call; 2) verifying the Exception thrown and 3) is consecutive stubbing:
import static org.junit.Assert.*;
import static org.mockito.Mockito.when;
import java.util.*;
import example1.dao.BookDao;
import example1.model.Book;
import example1.service.BookInventoryService;
import example1.service.MysteryBookInventoryService;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.runners.MockitoJUnitRunner;
import static org.mockito.Mockito.verify;
@RunWith(MockitoJUnitRunner.class)
public class InventoryServiceTest {
BookInventoryService service;
@Mock
private BookDao bookDao;
@Mock
private List <Book> mockedBooks;
@Mock
private Book mockedBook1;
@Mock
private Book mockedBook2;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this); //Important! Mocks need to be initialized.
service = new MysteryBookInventoryService();
service.setDataAccess(bookDao);
}
//verifying state and behavior
@Test
public void testGetInventory() {
when(bookDao.getBooks()).thenReturn(mockedBooks);
List <Book> resultList = service.getInventory();
//verify state
assertNotNull("Inventory should not be null", resultList);
//verify behavior
verify(bookDao).getBooks();
}
//verifying Exception
@Test(expected = Exception.class)
public void testGetInventoryById() throws Exception {
when(bookDao.getBookById(1)).thenReturn(null);
@SuppressWarnings("unused")
Book book = service.getInventoryById(1);
}
//Consecutive stubbing
@Test
public void testGetInventoryByIdManyTimes() throws Exception{
when(bookDao.getBookById(1)).thenReturn(mockedBook1, mockedBook2);
Book result = service.getInventoryById(1);
//verify 1 state
assertEquals(result,mockedBook1);
result = service.getInventoryById(1);
//verify 2 state
assertEquals(result,mockedBook2);
}
}
Subscribe to:
Posts (Atom)