Как отключить параметр для метода-заглушки с помощью Mockito - PullRequest
1 голос
/ 02 декабря 2010

Привет.

Я издеваюсь над поисковой системой для тестирования в моем веб-приложении.Эта поисковая система возвращает документы XML с различными схемами.Схема зависит от параметра, известного как набор сбора.Возврат различных схем на основе наборов наборов - это та часть, которую сложно высмеять, потому что указание набора наборов - это, по сути, метод настройки, и при этом недействительный.Эта поисковая система является внешним jar-файлом, поэтому я не могу изменить API.Я должен работать с тем, что было предоставлено.Вот пример:

Engine engine = factory.getEngine();
Search search = engine.getSearch();
search.addCollectionSet(someCollectionSet);
SearchResult result = search.getSearchResult();
Document[] documents = result.getAllDocuments();

Затем для каждого документа я могу получить xml, вызвав:

document.getDocumentText();

Когда я использую мои фиктивные объекты, getDocumentText() возвращает xmlстрока, созданная генератором, которая соответствует схеме.Я хочу использовать генератор другого типа в зависимости от того, какой набор сбора был предоставлен на шаге 3 в первом фрагменте кода выше.Я пытался сделать что-то вроде этого:

    doAnswer(new Answer() {
        Object answer(InvocationOnMock invocation) {
            if (args == "foo") {
                SearchResult result = getMockSearchResult();
                when(search.getSearchResult()).thenReturn(result);
            }
        }
    }).when(search.addCollectionSet(anyString()));

Но это приводит к большому красному выделению :)

В принципе, моя цель - отключить addCollectionSet(someCollectionSet), чтобыкогда он вызывается, я могу отключить параметр и убедиться, что используется другой генератор.Кто-нибудь знает, как я могу сделать что-то подобное?Или, может быть, существует какая-то форма Dependency Injection, которую можно использовать для условного подключения моего генератора?

Спасибо!

Обновление

У меня естьизменил мой заводской объект так, чтобы он никогда не возвращал движок, а скорее объекты поиска и поиска из этого движка, так что теперь я могу сделать что-то вроде этого:

Search search = factory.getSearch(collectionSet);

Так чтоЯ хотел бы сделать что-то вроде этого:

when(factory.getSearch(anyString()).thenAnswer(new Answer() {
    Object answer(InvocationOnMock invocation) {
        switch(args[0]) {
            case fooSet: return fooSearch; break;
            case barSet: return barSearch; break;   

Другими словами, я все еще хочу отключить строку, которая была передана getSearch в операторе switch.По общему признанию, я мог бы сделать что-то более похожее на то, что Феликс предложил ниже, но я бы предпочел, чтобы все мои дела были заключены в выключатель.Может кто-нибудь привести пример того, как это можно сделать?Спасибо!

Обновление

Я видел, что вы можете захватывать аргументы, которые передаются в ложные вызовы, но эти захваченные аргументы используются для более поздних утверждений.Я не видел, как можно отключить эти аргументы, чтобы при вызове моего макета возвращались разные значения в зависимости от аргументов.Кажется, должен быть способ сделать это, у меня просто нет опыта работы с Mockito, чтобы понять это.Но наверняка кто-то делает!

1 Ответ

1 голос
/ 02 декабря 2010

Я бы порекомендовал обернуть вызов унаследованного кода в ваш собственный объект.Таким образом, вы получите свой собственный метод в следующем формате:

class SearchEngineWrapper {
  public String getSearchResult(String collection){
    Engine engine = factory.getEngine();
    Search search = engine.getSearch();
    search.addCollectionSet(someCollectionSet);
    SearchResult result = search.getSearchResult();
    ...
    return document.getDocumentText();
  }
}

Теперь вы можете смоделировать этот метод.Этот метод также хорошо документирует ваши намерения.Также вы можете проверить фактическую реализацию в интеграционном тесте.

when(searchEngineWrapper.getSearchResult("abc").thenReturn("foo");
when(searchEngineWrapper.getSearchResult("xyz").thenReturn("bar");
...