2016-01-08 3 views
0

Мне нужно издеваться над защищенным методом в родительском классе моего класса под тестированием, но родительский класс находится в другом пакете, поэтому мой тестовый класс не может получить доступ к этому методу, поэтому я не может издеваться над этим. Должно быть решение этой проблемы без рефакторингаMock Protected Parent Method Когда родитель находится в другом пакете

Мне нужно использовать Powermock и Mockito. Вот баночки

  • Mockito-все 1.10.8
  • powermock-ядро 1.6.1
  • powermock-модуль-junit4 1.6.1
  • powermock-апи-Mockito 1.6.1
  • JUnit 4.12

Это устаревший код, поэтому я не могу реорганизовать, но вот упрощенный код.

Parent.java

package parent; 

public class Parent { 

    // Want to mock this protected parent method from different package 
    protected String foo() { 

     String someValue = null; 

     // Logic setting someValue 

     return someValue; 
    } 
} 

Child.java

package child; 

import parent.Parent; 

public class Child extends Parent { 

    String fooString = null; 

    public String boo() { 

     this.fooString = this.foo(); 

     String booString = null; 

     // Logic setting booString 

     return booString; 
    } 
} 

ChildTest.java

package child; 

import static org.mockito.Mockito.spy; 

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

import parent.Parent; 

@RunWith(PowerMockRunner.class) 
@PrepareForTest({ Parent.class, Child.class }) 
public class ChildTest { 

    // Class Under Test 
    Child cut; 

    @Before 
    public void setUp() throws Exception { 

     // Partial mock to mock methods in parent class 
     cut = spy(new Child()); 

    } 

    @Test 
    public void testBoo() { 

     // TODO: Need to mock cut.foo() but can't figure out how. 

     // Following gives me this error: The method foo() from the type Parent is not visible 
     Mockito.when(((Parent)cut).foo()).thenReturn("mockValue"); 

     // Test 
     cut.boo(); 

     // Validations 
     Assert.assertEquals(cut.fooString, "mockValue"); 

    } 
} 

ответ

3

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

@RunWith(PowerMockRunner.class) 
public class ChildTest { 

    @Test 
    public void testBoo() throws Exception { 
     //given 
     Child child = PowerMockito.spy(new Child()); 
     PowerMockito.when(child, "foo").thenReturn("mockValue"); 

     //when 
     String boo = child.boo(); 

     //then 
     Assert.assertEquals("boo+mockValue", boo); 
    } 
} 
3

Просто создайте новый кл ass для тестирования, расширяющего класс, который вы хотите проверить, и переопределите свой метод там.

Это будет выглядеть примерно так:

public class ChildForTest extends Child{ 
    @Override 
    protected String foo() { 
     //mock logic here 
    } 
} 

Edit: Если вы хотите, чтобы избежать нового определения класса можно использовать анонимный класс

@Before 
public void setUp() throws Exception { 

    // Partial mock to mock methods in parent class 
    cut = new Child(){ 
     @Override 
     protected String foo(){ 
      //mock logic here 
      return ""; 
     } 
    }; 
} 
+0

Я не хочу реорганизовывать Java. Я только хочу написать новый модуль тестирования модулей и использовать PowerMock и Mockito. – javaPlease42

+1

Вам не нужно реорганизовывать что-либо, вы просто создаете новый класс, который будет иметь этот метод foo, и вместо использования объекта Child в тесте вы можете использовать объект ChildForTest, поскольку единственная разница будет в том, как метод foo () works –

+0

Но это вводит новый класс. Все, что я пытаюсь сделать, - это охватить все Child.java, не входя в Parent.java. Поэтому я хочу охватить все Child.java, насмехаясь над всем в Parent.java. – javaPlease42

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