Mockito: InvalidUseOfMatchersException


141

У мене є інструмент командного рядка, який виконує перевірку DNS. Якщо перевірка DNS успішна, команда переходить до подальших завдань. Я намагаюся написати одиничні тести для цього за допомогою Mockito. Ось мій код:

public class Command() {
    // ....
    void runCommand() {
        // ..
        dnsCheck(hostname, new InetAddressFactory());
        // ..
        // do other stuff after dnsCheck
    }

    void dnsCheck(String hostname, InetAddressFactory factory) {
        // calls to verify hostname
    }
}

Я використовую InetAddressFactory для знущання над статичною реалізацією InetAddressкласу. Ось код заводу:

public class InetAddressFactory {
    public InetAddress getByName(String host) throws UnknownHostException {
        return InetAddress.getByName(host);
    }
}

Ось мій тестовий випадок:

@RunWith(MockitoJUnitRunner.class)
public class CmdTest {

    // many functional tests for dnsCheck

    // here's the piece of code that is failing
    // in this test I want to test the rest of the code (i.e. after dnsCheck)
    @Test
    void testPostDnsCheck() {
        final Cmd cmd = spy(new Cmd());

        // this line does not work, and it throws the exception below:
        // tried using (InetAddressFactory) anyObject()
        doNothing().when(cmd).dnsCheck(HOST, any(InetAddressFactory.class));
        cmd.runCommand();
    }
}

Виняток із запущеного testPostDnsCheck()тесту:

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: 
Invalid use of argument matchers!
2 matchers expected, 1 recorded.
This exception may occur if matchers are combined with raw values:
    //incorrect:
    someMethod(anyObject(), "raw String");
When using matchers, all arguments have to be provided by matchers.
For example:
    //correct:
    someMethod(anyObject(), eq("String by matcher"));

Будь-який вклад про те, як це вирішити?

Відповіді:


283

Повідомлення про помилку окреслює рішення. Лінія

doNothing().when(cmd).dnsCheck(HOST, any(InetAddressFactory.class))

використовує одне неочищене значення та один відповідник, коли потрібно використовувати або всі неочищені значення, або всі відповідники. Може бути прочитана правильна версія

doNothing().when(cmd).dnsCheck(eq(HOST), any(InetAddressFactory.class))

8
Як глупо мені. Я продовжував аналізувати, чому 2-й параметр продовжував давати мені помилку. Дякуємо за уточнення. Я дуже новачок у Мокіто, це моя перша зустріч.
деванг

32

У мене була дана проблема вже давно, мені часто потрібно було змішувати Матчери та цінності, і мені ніколи не вдавалося це робити з Mockito .... до недавнього часу! Я поклав рішення тут, сподіваючись, що воно допоможе комусь, навіть якщо ця посада досить стара.

Однозначно неможливо використовувати значення Matchers AND разом у Mockito, але що робити, якщо Matcher прийняв порівнювати змінну? Це вирішило б проблему ... а насправді є: екв

when(recommendedAccessor.searchRecommendedHolidaysProduct(eq(metas), any(List.class), any(HotelsBoardBasisType.class), any(Config.class)))
            .thenReturn(recommendedResults);

У цьому прикладі "метас" - це наявний список значень


5
Дивовижно. org.mockito.Mockito.eq()
javaPlease42

4
правильний імпорт тепер org.mockito.ArgumentMatchers.eq ()
Сем

15

Це може допомогти комусь у майбутньому: Mockito не підтримує глузування з «остаточних» методів (зараз). Це дало мені те саме InvalidUseOfMatchersException.

Для мене рішенням було скласти частину методу, яка не повинна бути «остаточною», в окремий, доступний і перезаписний метод.

Перегляньте API Mockito на предмет використання.


Це допомогло розібратися, чому мій код Котліна дасть мені помилку, адже всі методи в kotlin є остаточними!
sorry_I_wont

0

Не дивлячись на те, щоб використовувати всі відповідники, я отримував те саме питання:

"org.mockito.exceptions.misusing.InvalidUseOfMatchersException: 
Invalid use of argument matchers!
1 matchers expected, 3 recorded:"

Мені потрібно було небагато часу, щоб зрозуміти, що метод, який я намагався знущатися, - це статичний метод класу (скажімо, Xyz.class), який містить лише статичний метод, і я забув написати наступний рядок:

PowerMockito.mockStatic(Xyz.class);

Можливо, це допоможе іншим, оскільки це також може бути причиною проблеми.


0

Для мого випадку виняток було піднято, тому що я намагався знущатися над package-accessметодом. Коли я змінив рівень доступу до методу з packageдо protectedвиключенню пішло. Наприклад, нижче класу Java,

public class Foo {
    String getName(String id) {
        return mMap.get(id);
    }
}

метод String getName(String id)повинен бути на рівні найменшого protected рівня, щоб механізм глузування (підкласифікація) міг працювати.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.