Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Tomek Kaczanowski - Practical Unit Testing with JUnit and Mockito - 2013.pdf
Скачиваний:
228
Добавлен:
07.03.2016
Размер:
6.59 Mб
Скачать

Chapter 6. Things You Should Know

6.7. Mockito Matchers

Continuing our discussion on matchers, let us take a look at their use in specific, test-double related cases. So far we have been very specific as to the arguments of methods that we have been instructing Mockito to return when stubbing. Similarly, when verifying test doubles’ behaviour, we have expected certain methods to be called with certain values. For example, in Section 5.4.5 we verified whether client had received a specific message object or not. This makes sense, but sometimes expressing the arguments of calls in such detail is too rigid, as well as being simply unnecessary. In this section we will learn how to make our tests more relaxed by using argument matchers provided by Mockito.

But first things first, why bother at all with such a feature? Basically, there are two good reasons for doing so:

improved readability coming from the fact that code with matchers can be read like natural language (well, almost…),

improved maintainability thanks to the omitting of some unimportant details within the test code by means of more relaxed matchers.

Mockito offers a variety of predefined matchers which can be used for verification or stubbing. There are a great many of them, some being just aliases of others, simply for the sake of ensuring the readability of your tests. The list below gives only a subset of all of the matchers available10:

any() matches any object (or null),

anyVararg() matches any number and values of arguments,

isNull(), isNotNull() match null and not-null values respectively,

anyBoolean(), anyByte(), anyChar(), anyDouble(), anyFloat(), anyInt(), anyLong(), anyShort(),

anyString() match these Java types (or null),

isA(Class<T> clazz) matches any object of a given class,

same(T value) matches an object which is the same (==) to a given object,

anyCollection(), anyList(), anyMap(), anySet() matches any kind of instance of each sort of

collection (or null),

refEq(T value, String… excludeFields) matches an object that is reflection-equal to the given value; allows us to specify excluded fields, not to be taken into account,

eq(boolean value), eq(byte value), eq(char value), eq(double value), eq(float value), eq(int value), eq(long value), eq(short value), eq(T value) - matches values which are equal to given

arguments.

Many of the above methods also exists with additional arguments (of the java.lang.Class type) to make them generics-friendly: i.e. to avoid compiler warnings.

10For the full list of available matchers please refer to the Mockito documentation relating to the Matchers class.

114

Chapter 6. Things You Should Know

There are also some utility matchers for working with String arguments:

startsWith(String prefix), endsWith(String suffix) match a string that starts/ends with the prefix/

suffix that is given,

contains(String substring) matches a string that contains a given substring,

matches(String regex) matches a string that matches a given regular expression.

Such matchers are useful for specifying some "generic" stubbing behaviour or expectations. For example, such code will make the userDAO stub return the object user every time its getUser() method is called, regardless of what ID parameter is passed there.

Listing 6.16. Use of the anyInt() matcher

UserDAO userDAO = mock(UserDAO.class);

User user = new User();

when(userDAO.getUser(anyInt())).thenReturn(user);

assertEquals(user, userDAO.getUser(1)); assertEquals(user, userDAO.getUser(2)); assertEquals(user, userDAO.getUser(3));

verify(userDAO, times(3)).getUser(anyInt());

Stubbing of userDAO using an anyInt() matcher.

Verification that getUser() was called three times with some int argument.

The listing above shows you how to get rid of specific values and use more relaxed arguments when stubbing or verifying your code. This feature of Mockito is highly compatible with the approach that Mockito itself promotes – namely, only specifying in your tests what actually needs to be specified. So, if it is not crucial for your test logic that getUser() gets an argument equal to 789, then maybe anyInt() would be good enough? If so, do not hesitate. Work at the right abstraction level, hiding the unimportant details beneath the handy matchers we have just been learning about.

6.7.1. Hamcrest Matchers Integration

Last but not least, the Matchers class also provides a set of methods that will facilitate using custom Hamcrest matchers within your Mockito-based test code:

argThat(org.hamcrest.Matcher<T> matcher), which uses a given matcher,

booleanThat(Matcher<Boolean>

matcher),

byteThat(Matcher<Byte>

matcher),

charThat(Matcher<Character>

matcher),

doubleThat(Matcher<Double>

matcher),

floatThat(Matcher<Float>

matcher),

intThat(Matcher<Integer>

matcher),

longThat(Matcher<Long> matcher), shortThat(Matcher<Short> matcher), all of which will match on

the basis of matchers of the specified type.

By allowing any custom Hamcrest matcher to pass, we gain limitless possibilities for writing highly readable testing code. The use of matcher libraries in test code was discussed in Section 6.6, so right now let us conclude with just one example:

115

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]