Unit testing with Easymock

Embed Size (px)

Citation preview

Easy testing with EasyMock
(Java 5)

rgo RingoAqris Software

Developer tests - big theory

Why/whenshort feedback loop

Classic vs mock testinghttp://martinfowler.com/articles/mocksArentStubs.html

Failing legacy testscheck if can be fixed; if not separate from working ones

EasyMock mock types (1)

normal mocksexpect replay verify

@Before public void setUp() { userDao = EasyMock.createMock(UserDao.class); validator = new UserValidator(userDao); }

@Test public void duplicateLoginNameIsInvalid() throws Exception { User user = ... errors = new BindException(user, "User"); EasyMock.expect(userDao.isValidLoginName(user)).andReturn(false); EasyMock.replay(userDao);

validator.validate(user, errors);

assertTrue(errors.toString(), errors.hasErrors()); EasyMock.verify(userDao); }

Good practice is to assign mock object to field and create it inside setup method.

Where to put verify?

EasyMock mock types (2)

strict mockschecks order of calls

useful if test contains many different or complex scenarios (bad style?)

userDao = EasyMock.createStrictMock(UserDao.class);

Usually not very useful since we don't care about the order. Even if order is important test mostly fails anyway if wrong order of calls.

EasyMock mock types (3)

nice mocksuseful if default return value is OK

Warning: are you in getting it pass mode?

if cannot implement nice equals for some argument (but there is better alternative!)

filterDao = createNiceMock(FilterDao.class);

//expect(filterDao.getFilterId("unique-filter-name", USER_ID)).andReturn(null); replay(filterDao);

validator.validate(filter, errors);

assertFalse(errors.hasErrors()); verify(filterDao);

Does not care about input arguments.Returns default values.Works if you have no expects.

Argument matchers

when to useif default equals based check doesn't work

predefined matcherseq(X value)

aryEq(X value)

isNull(), notNull()

...

One cotcha if using arg matcher for one argument must also use for others

Custom argument matchers

useful if object equals doesn't work

mockSender.send(eqMessageText(simpleMessage));replay(mockSender);

sender.sendAccountApprovedNotification(user, password);verify(mockSender);

private SimpleMailMessage eqMessageText(final SimpleMailMessage expected) { EasyMock.reportMatcher(new IArgumentMatcher() {

public void appendTo(StringBuffer buffer) { }

public boolean matches(Object argument) { SimpleMailMessage actual = (SimpleMailMessage) argument; assertEquals(expected.getText(), actual.getText()); assertEquals(expected.getSubject(), actual.getSubject()); assertEquals(expected.getFrom(), actual.getFrom()); assertEquals(expected.getTo()[0], actual.getTo()[0]); return true; } }); return expected;}

Define answer at runtime

IAnwer interface

@Testpublic void showErrorsOnPage1() throws Exception { StepHandler stepHandler = createMock(StepHandler.class);

... stepHandler.validate(eq(step0.getModel()), (Errors) notNull()); expectLastCall().andAnswer(new IAnswer() {

public Object answer() { Errors errors = ((Errors) getCurrentArguments()[1]); errors.reject("Error occurred in one step"); return null; } }); replay(stepHandler); ...

verify(stepHandler);}

EasyMock more exotic stuff

for implementing stubsasStub() / asStubReturn()

asStubAnswer

mock only some methodscreateMock(Class, Method[])

EasyMock meets Unitils

import static org.unitils.easymock.EasyMockUnitils.*;

public class MockingTest extends UnitilsJUnit4 {

@Mock private UserDao userDao;

@Before public void setUp() { //userDao = createMock(UserDao.class); validator = new UserValidator(userDao); }

@Test public void duplicateLoginNameIsInvalid() throws Exception { User user = ... errors = new BindException(user, "User"); expect(userDao.isValidLoginName(user)).andReturn(false); //replay(userDao); replay();

validator.validate(user, errors); assertTrue(errors.toString(), errors.hasErrors()); //verify(userDao); verify(); }}

http://www.unitils.org/

EasyMock training

11.02.2008

Aqris Software

Click to edit the outline text formatSecond Outline LevelThird Outline LevelFourth Outline LevelFifth Outline LevelSixth Outline LevelSeventh Outline LevelEighth Outline LevelNinth Outline Level