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


class A {
protected obj init()
}
class B {
public void testingThis() {
//..stuff
obj = a.init()
moreStuff(obj)
}
}

我正在测试B班。我很难做到这一点,因为它使用了类A的方法来获取对象。我该如何解决这个问题?

p.S.不能改变能见度,不能放在同一个包裹里。

有了这样的约束,"最简单"的方法是在测试类或其包中声明一个类,该类将A作为要模拟的依赖项进行子类化
Stubinit()返回一个fixture数据,这应该没问题
您可以在存根类的构造函数中传递它。

这将给这个存根类,您可以在测试类中使用它作为依赖项:

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();
}
}

B在我看来写得不正确。对A的引用应该是一个注入的依赖项。现在您有两种方法来测试它:clean方法或PowerMock方法。如果你用干净的方法,你将重构B,使它有一个注入到a的依赖项,因此你可以用mock控制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();
}
}

最新更新