- jdk 1.6 installed
- eclipse or idea installed
- git installed
- git clone http://github.com/szczepiq/mockito-workshop.git
- alternatively, if don't have git, download (1.5 MB): https://github.com/szczepiq/mockito-workshop/zipball/master
- Import the project into your favorite IDE (that is: eclipse or IntelliJ :)
- Make sure the project builds & compiles in your IDE
- The instructor will start live-coding the exercises, please follow
Below stories are more like 'notes'. Once we get to work on the together things will get clear :)
- SmartDictionary delegates to Translator for translations. Start by adding org.workshop.SmartDictionaryTest with "shouldLookUpWords" method.
- "Only mock types you own", create Translator implementation that wraps the OnlineTranslator
- remembers the translation input and translation result via the History. Start by adding "shouldMaintainHistory" test.
- Use test constructor for 'boring' setup
Use @Mock, @InjectMocks annotations and the MocktioJUnitRunner
If History throws CannotUpdateHistory runtime exception. SmartDictionary should just warn in such case and not fail explosively. Start by adding "shouldIgnoreUnavailableHistory" test.
Modeling: use TranslationRequest in Translator
- Implement equals() to facilitate argument matching
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
History should use the TranslationRequest
- reuse argument matchers
- improve error message when args don't match
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()?
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
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
Demonstrate all tests work if SmartDictionary uses the RetryingTranslator and SafeHistory directly. Is it a good idea?
- Introduce dictionary factory - your dependency injection infrastructure
Refactor packages: model, app, dictionary, history, translator
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()
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
Refactor to separate packages: api, history, translators