Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Shell Java Groovy
branch: master
Failed to load latest commit information.
gradle/wrapper Refreshed Gradle
lib Refreshed Mockito version.
.classpath Updated eclipse metadata so that the project easily imports into ecli…
.gitignore Updated eclipse metadata so that the project easily imports into ecli…
.project Added the IDE (eclipse and idea) metadata so that importing the proje… After 20 mins of the workshop
build.gradle Refreshed Gradle
gradlew Refreshed Gradle
gradlew.bat Added gradle build infrastructure
mockito-workshop.iml Made IDEA aware of mockito sources.
mockito-workshop.ipr Refreshed the IDE metadata.

Workshop prerequisites

  1. jdk 1.6 installed
  2. eclipse or idea installed
  3. git installed

Workshop instructions

  1. git clone
  2. alternatively, if don't have git, download (1.5 MB):
  3. Import the project into your favorite IDE (that is: eclipse or IntelliJ :)
  4. Make sure the project builds & compiles in your IDE
  5. The instructor will start live-coding the exercises, please follow

Workshop stories

Below stories are more like 'notes'. Once we get to work on the together things will get clear :)

  1. SmartDictionary delegates to Translator for translations. Start by adding org.workshop.SmartDictionaryTest with "shouldLookUpWords" method.
  2. "Only mock types you own", create Translator implementation that wraps the OnlineTranslator
  3. remembers the translation input and translation result via the History. Start by adding "shouldMaintainHistory" test.
  4. Use test constructor for 'boring' setup
  5. Use @Mock, @InjectMocks annotations and the MocktioJUnitRunner

  6. If History throws CannotUpdateHistory runtime exception. SmartDictionary should just warn in such case and not fail explosively. Start by adding "shouldIgnoreUnavailableHistory" test.

  7. Modeling: use TranslationRequest in Translator

    • Implement equals() to facilitate argument matching
  8. TranslationRequest contains requestDate

    • write simple unit test for request date (TranslationRequestTest)
    • change the equals to contain the requestDate
    • Use the argument matcher
    • get rid of equals
  9. History should use the TranslationRequest

    • reuse argument matchers
    • improve error message when args don't match
  10. More Modeling: use TranslationResult in Translator

    • History should remember the TranslationResult
    • Use relaxed argument matchers in safe history test for all args
    • Use equals, discuss an argument matcher
    • Use argument captor
    • What's the alternative apart from matcher, captor and equals()?
  11. Retry the translation attempts up to X times. Start with "shouldRetryTranslations" test.

    • After implementing it in SmartDictionary, model the RetryingTranslator and move the unit tests accordingly
    • Refactor the tests
    • Don't forget about happy and unhappy tests for the feature
    • make the exceptions carry information about the failed attempts
  12. Break TranslationHistory operation into 2: translation attempt and translation completed. Start with "shouldTrackTranslationAttempts" test for the RetryingTranslatorTest

    • Explain the kinds of verification modes (atLeastOnce(), atLeast, atMost, never())
    • What do we do with the CannotUpdateHistory? Create SafeHistory implementation and move tests accordingly
    • refactor to SafeHistory to avoid try-catches in the SmartDictionary
  13. Demonstrate all tests work if SmartDictionary uses the RetryingTranslator and SafeHistory directly. Is it a good idea?

  14. Introduce dictionary factory - your dependency injection infrastructure
  15. Refactor packages: model, app, dictionary, history, translator

  16. Only use TranslationHistory if the keepHistory is enabled for SmartDictionary. Start with "shouldHistoryUpdatesBeConfigurable" test for SafeHistoryTest.

    • Use never() to make sure the interactions didn't happen
    • Refactor to use verifyNoMoreInteractions()
  17. TranslationResult contains the TranslationRequest

    • DefaultTranslator (the anti-corruption layer) needs tests
    • Use spy() to test if DefaultTranslator delegates and creates correct result
    • explain the difference between mockito spy and mockito mock
  18. Refactor to separate packages: api, history, translators

Something went wrong with that request. Please try again.