2015-05-29 7 views
1

Мне нужно сделать некоторые тесты jUnit для некоторых методов, и я не могу изменить исходный код. Есть ли возможность изменить поведение функции без изменения исходного кода? Посмотрите прямолинейный пример: Class A и B являются исходным кодом (не могут их изменить). Я хочу изменить поведение метода run() из A, когда я вызываю его в B через тестирование() в тесте Junit. Есть идеи?jUnit изменить поведение метода

public class A { 
    public String run(){ 
     return "test"; 
    } 
} 

public class B { 
    public void testing() { 
     String fromA = new A().run(); //I want a mocked result here 
     System.out.println(fromA); 
    } 
} 

public class C { 
    @Test 
    public void jUnitTest() { 
     new B().testing(); 
     // And here i want to call testing method from B but with a "mock return" from run()   
    } 
} 
+0

модульные тесты должны проверить свои методы, чтобы не изменить то, что они (как предполагается) сделать. Вы можете их высмеять. Посмотри Мокито. Это инструмент, который поможет вам высмеять результаты. – Stultuske

+0

Как бы вы использовали макет в этом случае? Без издевательского метода тестирования? –

+0

использовать javaassist для изменения поведения класса или методов, это библиотека манипулирования байтов. –

ответ

1

Вы можете использовать Mockito и PowerMock:

import org.junit.Before; 
import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.powermock.api.mockito.PowerMockito; 
import org.powermock.core.classloader.annotations.PrepareForTest; 
import org.powermock.modules.junit4.PowerMockRunner; 

import static org.mockito.Mockito.spy; 
import static org.mockito.Mockito.when; 

@RunWith(PowerMockRunner.class) 
@PrepareForTest(B.class) 
public class C { 
    @Before 
    public void setUp() throws Exception { 
     A a = spy(new A()); 
     when(a.run()).thenReturn("mock return"); 
     PowerMockito.whenNew(A.class).withNoArguments().thenReturn(a); 
    } 

    @Test 
    public void jUnitTest() { 
     new B().testing(); 
    } 
} 
0

Вы не можете проверить это так, как хотите, а не изменять исходный код. Вы не можете издеваться над локальными переменными. Я бы предложил вам добавить новый метод к B.class, который вернет new A() и spy, используя Mockito.

@Test 
public void test(){ 
    final B spy = Mockito.spy(new B());  
    Mockito.doReturn(new C()).when(spy).getA(); 
} 

class C extends A { 
    @Override 
    public String run(){return "new String";} 
} 

Использование библиотек байт в тестах не очень хорошая идея.

Смежные вопросы