ºÝºÝߣ

ºÝºÝߣShare a Scribd company logo
Easy testing with EasyMock (Java 5) ?rgo Ringo Aqris Software
Developer tests - big theory Why/when short feedback loop Classic vs mock testing http://martinfowler.com/articles/mocksArentStubs.html Failing legacy tests check if can be fixed; if not separate from working ones
EasyMock mock types (1) normal mocks expect ¨C replay ¨C 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 ); }
EasyMock mock types (2) strict mocks checks order of calls
useful if test contains many different or complex scenarios (bad style?)  userDao  = EasyMock. createStrictMock (UserDao. class );
EasyMock mock types (3) nice mocks useful 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 );
Argument matchers when to use if default equals based check doesn't work predefined matchers eq(X value)
aryEq(X value)

More Related Content

Unit testing with Easymock

  • 1. Easy testing with EasyMock (Java 5) ?rgo Ringo Aqris Software
  • 2. Developer tests - big theory Why/when short feedback loop Classic vs mock testing http://martinfowler.com/articles/mocksArentStubs.html Failing legacy tests check if can be fixed; if not separate from working ones
  • 3. EasyMock mock types (1) normal mocks expect ¨C replay ¨C 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 ); }
  • 4. EasyMock mock types (2) strict mocks checks order of calls
  • 5. useful if test contains many different or complex scenarios (bad style?) userDao = EasyMock. createStrictMock (UserDao. class );
  • 6. EasyMock mock types (3) nice mocks useful if default return value is OK
  • 7. Warning: are you in ¡°getting it pass¡± mode?
  • 8. 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 );
  • 9. Argument matchers when to use if default equals based check doesn't work predefined matchers eq(X value)
  • 12. ...
  • 13. 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; }
  • 14. D efine answer at runtime IAnwer interface @Test public void showErrorsOnPage1() throws Exception { StepHandler stepHandler = createMock(StepHandler.class); ... stepHandler.validate( eq ( step0 .getModel()), (Errors) notNull ()); expectLastCall ().andAnswer( new IAnswer<Object>() { public Object answer() { Errors errors = ((Errors) getCurrentArguments ()[1]); errors.reject( &quot;Error occurred in one step&quot; ); return null ; } }); replay (stepHandler); ... verify (stepHandler); }
  • 15. EasyMock more exotic stuff for implementing stubs asStub() / asStubReturn()
  • 16. asStubAnswer mock only some methods createMock(Class<T>, Method[])
  • 17. 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, &quot;User&quot; ); 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/

Editor's Notes

  • #4: Good practice is to assign mock object to field and create it inside setup method. Where to put verify?
  • #5: Usually not very useful since we don&apos;t care about the order. Even if order is important test mostly fails anyway if wrong order of calls.
  • #6: Does not care about input arguments. Returns default values. Works if you have no expects.
  • #7: One cotcha ¨C if using arg matcher for one argument must also use for others