调用受保护方法的测试方法构成另一个类

时间:2018-12-14 12:09:19

标签: testing reflection junit mockito

descriere

我正在测试class A { protected obj init() } class B { public void testingThis() { //..stuff obj = a.init() moreStuff(obj) } } 类。我这样做很麻烦,因为它使用类B的方法来获取对象。我该如何解决?

P.S。无法更改可见性,不能放入同一包装中。

2 个答案:

答案 0 :(得分:0)

在这样的约束下,“最简单的”是在测试类或其包中声明一个类,该类将A子类化为要模拟的依赖项。
存根init()返回固定装置数据,应该没问题。
您可以在存根类的构造函数中传递它。

这将为您提供此存根类,您可以将其用作测试类中的依赖项:

class StubA extends A {

    Foo stubbedFoo;
    public StubA(Foo stubbedFoo){this.stubbedFoo=stubbedFoo}

    @Override
    public Foo init(){
       return stubbedFoo;
   }
}

测试样本:

class BTest {

    @Test
    public void doThat() {
      StubA a = new StubA(anyFooValue);
      B b = new B(a);
      // action
      b.doThat();
    }
}

答案 1 :(得分:0)

我认为B书写不正确。对A的引用应该是注入依赖性。现在,您可以通过两种方法进行测试:干净方法或PowerMock方法。如果您采用简洁的方式,则将重构B,以便将其依赖项注入A,因此您可以通过模拟来控制A类。

class B {
    A myAclass;

    @Inject
    public B(A myAclass) {
        this.myAclass=myAclass;
    }

    public void testingThis() {
      //..stuff
      obj = myAclass.init()
      moreStuff(obj)
    }
}

现在测试可以看起来像这样:

@RunWith(MockitoJUnitRunner.class)
public class Btest {
    @Mock
    A myAmock; 

    @InjectMocks
    B sut; // System-Under-Test

    @Test
    public void testB() {
        X theObject = mock(X.class);
        when(myAmock.init()).thenReturn(theObject);

        // call the method
        sut.testingThis();

        //verify the call being done
        verify(a, times(1)).init();
    }
}

如果您无法更改B的代码,您仍然可以对其进行测试,但为此需要PowerMock(ito)。

@RunWith(PowerMockRunner.class)
@PrepareForTests({A.class, B.class})
public class Btest {
    B sut;

    @Test
    public void testB() {
       A aMock = mock(A.class);
       X thObject = mock(X.class);

       // I can't determine from the code if the init method is static or you use an instance. In case of an instance you must override the constructor:
       PowerMockito.mockStatic(A.class);
       PowerMockito.whenNew(A.class).withNoArguments().thenReturn(aMock);
       when(aMock.init()).thenReturn(theObject);

       // In case of a static method you should mock that method
       when(A.init()).thenReturn(theObject);

       // Now construct B to test it.
       sut = new B();
       sut.testingThis();

       // verify
       verify(aMock, times(1)).init();
    }
}