2016-10-25 10 views
1

У меня есть код, похожий на этотКак я могу издеваться унаследованным методом класса я тестирование

class Util{ 
public String transform(String str); 
//lots of logic including ajax calls 
return("Modified"+str); 
} 
public caseChange(String str){ 
//lots of logic including ajax calls 
return str.toUpperCase()  
} 

class TextParser extends Util{ 
public String parse(str) 
//lots of logic to modify str 
str = caseChange(str); 
//some more logic to modify str 
return transform(str); 
} 

Есть в любом случае, чтобы дразнить caseChange и трансформировать методы возвращают некоторые издевались данных и предотвратить вызов на суперкласса, когда я звоню

String result = new TextParser().parse("hello") 

в классе единицы измерения для утверждения результата.

Преобразование и changeCase в моем примере упрощены. В действительности они выполняют вызовы ajax, и есть тонна другой логики. Я хочу издеваться над ними так, чтобы можно было протестировать только эту часть, а затем выполнить тестирование супер методов.

ответ

1

В данном примере: вы просто этого не делаете. Ваши методы: только, работающий на ваших входах; поэтому не должно быть не вопрос, где эти методы реализованы.

Другими словами: вам представляется наиболее подходящим для вас сосредоточиться на проверке договора . Как:

@Test 
public testWhatever() { 
    assertThat(new TextParser.parse("hello"), is("expected output")); 
} 

Да, вы можете вероятно издеваться такие вещи, используя Mockito/Powermock; но вы не должны! Вы видите, ваш производственный код напрямую вызывает эти методы; так что вы хотите , чтобы проверить, что вызов разобрана дает ожидаемые результаты

Edit (при использовании всего кода, который также будет работать на установке производства!): учитывая Ваш комментарий о том, что методы быть «сложным». Тогда я предлагаю: do не используйте наследование здесь. Вы должны не сделать класс B подклассом A, чтобы иметь легкий доступ к некоторым методам. Другими словами: наследование составляет около моделирование отношение IS-A. Итак, TextParser - Util? Звучит не очень убедительно.

Таким образом: вы должны перейти на состав здесь. Ваш TextParser следует использовать a Util объект. И это может быть обеспечено посредством инъекции зависимостей; и ваша потребность в издевательствах с унаследованными методами полностью исчезает!

+0

В моем примере упрощенные преобразования и changeCase упрощены. В действительности они выполняют вызовы ajax, и есть тонна другой логики.Я хочу издеваться над ними так, чтобы он мог тестировать только эту часть, а затем повторить тестирование супер методов –

+0

См. Мой обновленный ответ. – GhostCat

1

Вы, возможно, потребуется создать еще один подкласс, как

class TextParserForTest extends TextParser { 
     @Override 
     public String parse(String str) { 
       super.parse(str); 
     } 

     @Override 
     public String caseChange(String str) { 
       return "whatever"; 
     } 
} 

редактировать: использование Mockito к этому:

import static org.mockito.Mockito.*; 

import org.junit.Test; 

@Test 
public void test() { 
    TextParser tp = mock(TextParser.class); 

    // all the methods that you want to test 
    when(tp.parse(any())).thenCallRealMethod(); 
    when... 

    // all the methods that you want to mock 
    when(tp.caseChange(any()).thenReturn("whatever"); 
    when... 
} 
+0

Мне нужно написать 25 тестовых примеров в классе :( Есть ли способ сделать это с помощью powermock или mockito? –

+0

попробуйте, когда (textParse.caseChange (anyString()). ThenReturn ("whatever"); –

+0

Я пробовал это с помощью новый объект Util и TextParser. Он все еще идет в суперкласс –

0

Вы можете использовать функцию шпиона Mockito. Шпион называет реальные методы, если они не затушеваны.

@Test 
public void testParse() { 
    TextParser textParser = Mockito.spy(new TextParser());   
    when(textParser.caseChange(Matchers.anyString())).thenReturn("mocked"); 
    Assert.assertEquals("Modifiedmocked", textParser.parse("hello")); 
}