2016-05-15 1 views
2

Я тестирую функцию класса A func1.Как переопределить метод в модульных тестах, который вызывается, из которого тестируется класс.

Func1 имеет локальную переменную класса B и вызывает функцию B func2. Код выглядит примерно так:

public Class A 
{ 
    public func1() 
    { 
     B object = new B(); 
     int x = object.func2(something); 
    } 
} 

Когда я тестирую func1 в своих модульных тестов, я не хочу, чтобы func2 называется.

Так что я пытаюсь сделать что-то вроде этого в тесте:

B textObject = new B() 
{ 
    @override 
    int func2(something) 
    { 
     return 5; 
    } 
} 

Но он по-прежнему называя func2 в классе B. Пожалуйста, предложите, как справиться с этим.

+1

Вы могли бы использовать инъекции зависимостей, рефакторинг 'A' взять' b' в качестве аргумента вместо создания «новой» функции внутри функции? С таким абстрактным примером трудно дать разумные советы. – jonrsharpe

+0

Я не могу взять B как вход в конструкторе A ни в func1, как в качестве ввода, потому что я переопределяю func1 в классе A. Я могу сделать B как переменную класса в A, но это, похоже, не помогает или. Что бы вы предложили в этом случае? –

+1

Я не уверен, в чем проблема; опять же, пример слишком абстрактный. Проведите некоторое исследование вокруг DI. – jonrsharpe

ответ

2

Если вы хотите переопределить вызов конструктора new B() - поместите его собственным методом.

public Class A 
{ 

    public func1() 
    { 
     B object = newB(); 
     int x = object.func2(something); 
    } 

    protected B newB(){ 
     return new B(); 
    } 
} 

В тесте вы можете переопределить вызов B конструктора.

public class APartitialMock extends A { 

    protected B newB(){ 
     return new BMock(); 
    } 
} 

public class BMock extends B { 

    int func2(something) { 
     return 5 
    } 

} 

APartitialMock Затем используйте для проверки func1 с видом B.

PS Если вы или хотите использовать принять рамочный взглянуть на powermock - Mock Constructor

+0

Я закончил тем, что решил эту инъекцию зависимости от инъекций, но это отличный совет! Благодаря! –

0

я могу сделать В качестве переменной класса в А, но это не похоже, чтобы помочь либо. Что бы вы предложили в этом случае?

Если вы сделаете B в качестве переменной класса, то вы можете издеваться B, и «своп» это в исследуемом объекте А.
Может быть, не очень элегантно, но быстро и просто.

Пример:

public class B { 
    int func2(int something){ 
     return 3*something; 
    } 
} 

public class A 
{ 
    // declare it as protected - a test need to have access to this field to replace it 
    protected B object = new B(); 

    public int func1() 
    { 
     int x = object.func2(22); 
     return x; 
    } 
} 

И тест:

import static org.mockito.Mockito.*; 
import static org.junit.Assert.*; 

import org.junit.Test; 

public class ATest { 

    @Test 
    public void test() { 
     A myA = new A(); 
     B myB = mock(B.class); 

     // dummy function 
     when(myB.func2(anyInt())).thenReturn(20); 

     // replace B with mocked B 
     myA.object = myB; 

     int actual = myA.func1(); 

     assertEquals(20, actual); 
    } 
} 
Смежные вопросы