This course will get you up to speed with JUnit and TDD in next to no time with a mixture of Instant Demos, Deep Dives and Philosophy lectures.
In the Instant Demo you’ll quickly get a feeling for how things will work once you’re an expert. No getting distracted by detail, just the real life feel of using the techniques.
With a Deep Dive we will unpack all the necessary detail to enrich your understanding.
The Philosophy lectures will give you the fundamentals from which you can grow your own knowledge.
Building your knowledge from the inside out with realistic examples means you will understand TDD quickly and deeply. Hopefully this course will make you excited about what TDD can do for you.
Includes:
JUnit 4.12
Mockito 2
Spring Testing
Parameterized tests
Various other JUnit runners
Written by the author of The Coding Craftsman WordPress blog.
Introduction
In this first lecture, we discuss the structure and methodology of the course and share the Git repository URL, which is https://github.com/ashleyfrieze/instant-tdd
The Basics
With the use case of a leap year detector, this is a quick demo of TDD in action. You should see how it feels to write tests first, using your IDE to generate enough code to make the software compile and writing small implementations to make the tests pass.
Revisiting the code from the TDD Instant Demo, this will look at how JUnit and TDD is used in a little more detail.
The deep dive shows how each element of TDD and JUnit comes together to make testing and coding work hand in hand.
Revisiting the leap year algorithm, this lecture explores how to cultivate an algorithm by iteratively adding tests to cover use cases, refactoring the code when it gets too complex.
This shows TDD with a very lightweight set of JUnit practices. The intention is to show how TDD scales to larger problems.
Showing examples of TDD is a good way to get the rhythm of doing it and the syntax of the tool set. This lecture will explain the thinking behind TDD and what is in it for you.
In every technique you learn, there is usually some underlying pattern. In the case of TDD, each test has a natural form. This lecture explains what's underneath all testing techniques so you can recognise tests that are unusually formed and tests which are a perfect example of the craft.
Using a more challenging example - a unique word counter - this is a demo of the tools of TDD being used to craft more complex code.
Creating a shareable project with code and tests in Java can be tricky. Luckily your IDE and Maven can help. This is a quick demo showing how the example projects in this course were created.
For those people who wish not to use IntelliJ as their IDE or who wish to set up projects from the command line, this version of project set up shows how to use the maven command from the command line. One simple command can build the barebones project in which tests and conventional code can be developed.
Having covered a subset of JUnit's features, this section summary puts together what we have learned so far, covering the process, the benefits and recapping the shape of JUnit test code.
Basic Testing with Mocks using Mockito
Instant demo of Mockito in action.
Where there are services that might touch the outside world, you use mocks to test your core algorithms. This example, based around distributing articles from a data source to the right receiving services, uses Mockito to eliminate dependencies on real implementations.
Having used Mockito, let's unpack how it did what it did in the demo.
The Mockito JUnit runner is a plug-in for JUnit which takes away the boilerplate of setting up test objects with mocks. In this lecture the example from the Instant Demo is refactored to use a more declarative approach with less code.
After looking at the Mockito library to do some basic mocking and stubbing, this lecture takes a look at what mocking is all about. It covers the motivations towards mocking and how mocking drives good design into the code. It also looks at what happens if mocking is over or under used.
JUnit in more Depth
The JUnit Assertions library is used at the heart of testing to prove the outcome of tests are correct. This is a tour of the different types of assertion.
When you want to prove that a method throws an exception, JUnit has an extension to the @Test annotation to help you.
When a test should not be expected to take more than a certain amount of time, and you do not want code stuck in an infinite wait to break your builds, you can add a timeout to your test. This is especially useful for testing concurrent code.
Tests methods or classes can be marked as ignored to stop them breaking a build or distracting you during development. This is a useful feature, but beware of what happened to Jan!
JUnit finds your test classes, runs your test code and hooks in any set up and tidy up you need. This lecture uncovers all the main lifecycle events and what they are best used for.
We heard about Before and After in the lifecycle lecture. Here is a quick demo. It shows how to pull per-test set-up into a method, using the instance members of the class to track it, and even performing post-test assertions.
Rules are another way to hook behaviour into your JUnit tests. The Expected Exception rule is a cleaner way of testing exceptions.
Once I discovered this part of JUnit, it changed my tests forever! The TemporaryFolder rule is a must-have for managing files during testing. The example from the Before and After lecture is refactored again to use it.
There are two key extension points for JUnit's lifecycle. Test runners and test rules. This lecture explores the purpose of each and why both are needed.
There is a list of custom runners at https://github.com/junit-team/junit4/wiki/Custom-runners
More Assertions
Make your assertions read more easily from left to right by using assertThat and hamcrest matchers.
AssertJ is an open source assertions library which is well worth looking at. It can be found at http://joel-costigliola.github.io/assertj/
This lecture shows how AssertJ makes asserting even easier.
Parameterized Tests
Some tests are repetitive and would benefit from a more data driven approach. This lecture explores the rationale of parameterized tests.
Refactoring the original leap year example to have a single test method and an input table of test data using the built in JUnit Parameterized runner.
A deeper look at how the Parameterized runner executed our tests.
Refactoring the leap year example to use the JUnitParams runner where each test method can have its own input parameters.
Further information on JUnitParams, where to find it, and where to get more examples. Especially here - https://github.com/Pragmatists/JUnitParams
A last look at the benefits of parameterized tests and how to incorporate them into a TDD process.
Mockito in more Depth
Introduction to the Mockito in More Depth section including some basics on ArgumentMatchers.
How to make a mock return different things either when the inputs vary, or on subsequent calls.
Verifying the number of calls, handling concurrent tests, argument captors and how to avoid them.
To test try/catch code paths you often need to make your mocks simulate exceptions being thrown.
Rather than provide an explicit mapping of response to input, Mockito Answers let you hook the behaviour of your mock to something more dynamic.
A worked example of a Mockito Spy.
The BDD Mockito variation of syntax is cleaner. Here's a transformation from classic to BDD Mockito syntax.
Sometime the when/then or given/will syntax is not able to mock for a certain scenario. There is another way.
With Java 8 functional interfaces, perhaps we don't need Mockito at all.
Testing Spring with SpringJUnitRunner
This shows a spring context being built up from nothing, along with tests that support it, and test the functionality of the beans within it. There is practical advice on how to manage this more complicated development and test scenario.
This unpacks the things that go into a Spring test, including maven dependencies and the correct annotations for the test class.
Growing a web application through tests is relatively easy to do, especially if you do it in small steps. In this example, we take the skeleton of a Rest API and by adding small increments to it, make it work.
This is a long walk-through, showing technology and process, with mishaps along the way illustrating how to troubleshoot when problems occur.
Other JUnit Runners
As a contributor to this open source project, perhaps it's down to me to show you how to use it.
See https://github.com/greghaskins/spectrum for more information on the tool.
This lecture just scratches the surface, but shows a completely different approach to testing, which is hopefully thought provoking.
Some final thoughts
With the lectures done, it's over to you to put this knowledge into practice. Here are some final bits of guidance.