Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Mockito Essentials

You're reading from   Mockito Essentials A practical guide to get you up and running with unit testing using Mockito

Arrow left icon
Product type Paperback
Published in Oct 2014
Publisher
ISBN-13 9781783983605
Length 214 pages
Edition 1st Edition
Tools
Arrow right icon
Author (1):
Arrow left icon
Sujoy Acharya Sujoy Acharya
Author Profile Icon Sujoy Acharya
Sujoy Acharya
Arrow right icon
View More author details
Toc

Working with unit tests

A common understanding of unit testing is the testing of the smallest possible part of software, such as a single method, a small set of related methods, or a class.

In reality, we do not test methods; we test a logical unit and its behavior instead. Logical units can extend to a single method, to an entire class, or a collaboration of multiple classes.

For example, a standard calculator program can have an add method for adding two numbers. We can verify the add behavior by invoking the add method, or we can design the calculator program to have a simple calculate API, which can take two numbers and an operation (add, subtract, divide, and so on). Depending on the operand type (integer, double, and so on), the calculator may delegate the calculation to a collaborator class, such as a double calculator or a long calculator. We can still unit test the add behavior, but multiple classes (units) are involved now.

A unit test verifies an assumption about the behavior of the system. Unit tests should be automated to create a safety net so that the assumptions are verified continuously and a quick feedback can be provided if anything goes wrong.

The following are the benefits of test automation:

  • Behavior is continually verified: We refactor code (change the internal structure of the code without affecting the behavior of the system) to improve the code's quality, such as maintainability, readability, or extensibility. We can refactor code with confidence if automated unit tests are running and giving feedback.
  • The side effects of code changes are detected immediately: This is useful for a fragile, tightly-coupled system, where a change in one module breaks another module.
  • Saves time; no need for immediate regression testing: Suppose that you are adding a scientific computational behavior to an existing calculator program and modifying the code; after every piece of change, you do a regression testing to verify the integrity of the system. Manual regression testing is tedious and time-consuming, but if you have an automated unit test suite, then you can delay the regression testing until the functionality is done. This is because the automated suite will inform you at every stage if you break an existing feature.

A unit test should exhibit the following characteristics:

  • It should be automated, as explained in the preceding section.
  • It should have a fast test execution. To be precise, a test should not take more than a few milliseconds to finish execution (they should be fast; the faster, the better). A system can have thousands of unit tests. If they take time to execute, then the overall test execution time will go up; as a result, no one will be interested in running the tests. It will impact the feedback cycle.
  • A test should not depend on the result of another test or rather test execution order. Unit test frameworks can execute tests in any order. So, if a test depends on another test, then the test may fail any time and provide wrong feedback. You want tests to be standalone so that you can look at them and quickly see what they're actually testing, without having to understand the rest of the test code.
  • A test should not depend on database access, file access, or any long running task. Rather, an appropriate test double should isolate the external dependencies.
  • A test result should be consistent and time-and-location transparent. A test should not fail if it is executed at midnight, or it should not fail if it is executed in a different time zone.
  • Tests should be meaningful. A class can have getter and setter methods; you should not write tests for the getters and setters because they should be tested in the process of other more meaningful tests. If they're not, then either you're not testing the functionality or your getters and setters aren't being used at all; so, they're pointless.
  • Tests are system documentation. Tests should be readable and expressive; for example, a test that verifies the unauthorized access could be written as testUnauthorizedAccess() or rather when_an_unauthorized_user_accesses_the_system_then_raises_secuirty_error(). The latter is more readable and expresses the intent of the test.
  • Tests should be short and tests should not be treated as second-class citizens. Code is refactored to improve the quality; similarly, unit tests should be refactored to improve the quality. A test class of 300 lines is not maintainable; we can rather create new test classes, move the tests to the new classes, and create a maintainable suite.

As per the preceding best practices, a test should be executed as fast as possible. Then what should you do if you need to test data access logic or file download code? Simple, do not include the tests in an automated test suite. Consider such tests as slow tests or integration tests. Otherwise, your continuous integration cycle will run for hours. Slow tests should still be automated. However, they may not run all the time, or rather they should be run out of the continuous integration feedback loop.

You cannot automate a unit test if your API class depends on slow external entities, such as data access objects or JNDI lookup. Then, you need test doubles to isolate the external dependencies and automate the unit test.

The next section covers test doubles.

You have been reading a chapter from
Mockito Essentials
Published in: Oct 2014
Publisher:
ISBN-13: 9781783983605
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime
Banner background image