Как заглушить varargs в Mockito, чтобы соответствовать только одному аргументу - PullRequest
3 голосов
/ 18 марта 2019

Я хотел бы заглушить некоторый код, чтобы метод vararg возвращал true, когда один из аргументов соответствует определенному значению.Например, учитывая существующий код, который я не могу изменить:

(здесь используется Kotlin, но я думаю, что это применимо к любой ситуации с Java.)

class Foo {
    fun bar(vararg strings : String) : Boolean {
        // Iterates `strings` and returns true when one satisfies some criteria
    }
}

... Я хочунаписать код заглушки, подобный этому:

val foo = Foo()
whenever(foo.bar(eq("AAA"))).thenReturn(true)

Это прекрасно работает, когда вызов точно foo.bar("AAA").

Однако бывают случаи, когда код подtest делает вызов foo.bar("AAA", "BBB"), и в этих случаях происходит сбой.

Как я могу изменить мой код заглушки, чтобы он работал, когда в вызове передается любое количество varargs?

Редактировать Помечено как возможное Дубликат ;в этом случае сценарий предусматривает полное отсутствие varargs в вызове.Здесь я пытаюсь сопоставить один конкретный элемент массива varargs.

Ответы [ 2 ]

4 голосов
/ 18 марта 2019

Вы должны заглушить свой метод 2 раза. Первый наименее конкретный заглушка:

val foo = Foo()
whenever(foo.bar(any())).thenReturn(false) // or whatever you want to return/throw here

А затем более конкретный метод с одним аргументом:

whenever(foo.bar(eq("AAA"))).thenReturn(true)

После вашего комментария вы также можете использовать что-то вроде этого (на этот раз с Java):

when(foo.bar(any())).thenAnswer(invocation -> {
    for (Object argument : invocation.getArguments()) {
        if ("AAA".equals(argument)) return true;
    }
    return false;
});

И то же самое в Котлине

whenever(foo.bar(any()).thenAnswer {
    it.arguments.contains("AAA")
}
2 голосов
/ 18 марта 2019

Вы можете создать свой собственный matcher:

public class MyVarargMatcher extends ArgumentMatcher<String[]> implements VarargMatcher
{
    private String expectedFirstValue;

    public MyVarargMatcher(String expectedFirstValue)
    {
        this.expectedFirstValue = expectedFirstValue;
    }

    @Override
    public boolean matches(Object varargArgument) {
        if (varargArgument instanceof String[])
        {
            String[] args = (String[]) varargArgument;
            return Stream.of(args).anyMatch(expectedFirstValue::equals);
        }
        return false;
    }
}

А затем используйте его вот так (код Java):

Foo foo = Mockito.mock(Foo.class);
Mockito.doReturn(true).when(foo).bar(Mockito.argThat(new MyVarargMatcher("AAA")));

отредактировано с комментарием оп: Пока "AAA" является одним из аргументов, оно должно возвращать true

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...