Search code examples
javaunit-testingjunithamcrest

Is it acceptable to use Hamcrest matchers in non test code


I am trying to find a definitive answer to using Hamcrest matchers in non test code. I have done a bit of research, and have some contrasting quotes:

  • Hamcrest on Wikipedia:

    Hamcrest is a framework that assists writing software tests in the Java programming language. [snip] These matchers have uses in unit testing frameworks such as JUnit 2 and jMock.

  • Hamcrest on Github:

    Hamcrest is a library of matchers, which can be combined in to create flexible expressions of intent in tests.

  • Hamcrest on Google Code:

    Note: Hamcrest it is not a testing library: it just happens that matchers are very useful for testing.

Personally, I associate Matchers with tests, so I tend to avoid using them outside of tests. That said though, I can see no limitations which would prevent them being used outside of a test scope.

Does this then come down to a personal preference?


Solution

  • I have used Hamcrest in non-test code several times until now. Mostly I use it when I want to test different conditions on the same object to get an report of what condition(s) failed for what reasons. The single conditions are then represented as different objects which also has some other good effects. For example inspecting the application configuration can yield results which data is supported for which operations.

    Reasons why I especially use hamcrest for this type of task:

    • it was designed to do this (testing conditions is not only done in test code)
    • it doesn't bring additional dependencies along
    • widely known as many use it already for test code
    • has an easy to use and small API
    • is easily extendable and supports composition very well

    At last it boils down to choose the right tool for the job. For example Bean validation can be used to do relatively similar jobs. Than a thoughtful decision needs to be made, which also incorporates the requirements of the development process and environment.

    Also using matchers is a good way to employ the Tell, don't Ask principle. You can pass a matcher to method to indicate what return value you are expecting to be returned. If the object in question doesn't match with that matcher, then an exception with a good description of the error can immediately be thrown.

    Also when comparing the use of matchers with the Predicate of java 8 the matchers have the benefit of being able to provide a description but the downside that they are not a functional interface themself.