2

在提问之前,让我解释一下当前的设置:

我有一个服务接口,比如 Service,还有一个实现,比如 ServiceImpl。这个 ServiceImpl 使用了一些其他的服务。所有的服务都被spring加载为bean。

现在,我想为 ServiceImpl 编写 junit 测试用例。同样,我使用 applicationContext 来获取 Service bean,然后在其上调用不同的方法来测试它们。

公共方法看起来一切都很好,但我如何为私有方法编写测试用例?因为对于不同的实现,我们可能没有相同的私有方法?

任何人都可以在这里帮助我编写测试用例的首选方式吗?

4

5 回答 5

5

纯粹的答案是私有方法被称为是有原因的!;-)

把问题转过来:只给定一个(可公开访问的)接口的规范,在编写代码之前你将如何布置你的测试计划?该接口描述了实现它的对象的预期行为;如果在该级别上无法测试,则说明设计有问题。

例如,如果我们是一家运输公司,我们可能有这些(伪编码)接口:

CapitalAsset {
    Money getPurchaseCost();
    Money getCurrentValue();
    Date  whenPurchased();
    ...
}

PeopleMover {
    Weight getVehicleWeight();
    int    getPersonCapacitly();
    int    getMilesOnFullTank();
    Money  getCostPerPersonMileFullyLoaded(Money fuelPerGallon);
    ...
}

并且可能有包括这些的类:

Bus implements CapitalAsset, PeopleMover {
    Account getCurrentAdvertiser() {...}
    boolean getArticulated() {...}
    ...
}

Computer implements CapitalAsset {
    boolean isRacked() {...}
    ...
}

Van implements CapitalAsset, PeopleMover {
    boolean getWheelchairEnabled() {...}
    ...
}

在设计CapitalAsset概念和界面时,我们应该与财务人员就任何实例的CapitalAsset行为方式达成一致。我们将CapitalAsset根据该协议编写针对该协议的测试;我们应该能够在 、 等上运行这些测试,而不依赖于涉及哪个具体类。同样对于.BusComputerVanPeopleMover

如果我们需要测试与 aBus无关的东西CapitalAssetPeopleMover那么我们需要单独的总线测试。

如果一个特定的具体类具有如此复杂的公共方法,以至于 TDD 和/或 BDD 无法清晰地表达它们的预期行为,那么这又是一个错误的线索。如果具体类中有私有的“帮助器”方法,它们应该出于特定原因而存在;应该可以问“如果这个助手有缺陷,什么公共行为会受到影响(以及如何)?”

对于合法的、固有的复杂性(即来自问题域),一个类可能适合拥有对特定概念负责的辅助类的私有实例。在这种情况下,辅助类应该是可自行测试的。

一个好的经验法则是:

如果测试太复杂,那就太复杂了!

于 2009-01-09T12:47:10.023 回答
4

私有方法应该通过类的公共接口来执行。如果您有同一个接口的多个实现,我会为每个实现编写测试类。

于 2009-01-09T11:53:08.150 回答
1

您已经编写了一个接口的多个实现,并希望使用相同的 JUnit4-test 测试所有实现。在下文中,您将看到如何做到这一点。

还有一个例子展示了如何为每个测试用例获取一个新实例。

示例代码在我开始解释之前,这里有一些java.util.list接口示例代码:

public class ListTest {

  private List<Integer> list;

    public ListTest(List<Integer> list){
      this.list = list;
    }

    @Parameters
    public static Collection<Object[]> getParameters() {
      return Arrays.asList(new Object[][] {
        { new ArrayList<Integer>() },
        { new LinkedList<Integer>()}
      });
    }

    @Test
    public void addTest(){
      list.add(3);
      assertEquals(1, list.size());
    }
}
于 2020-02-13T14:53:46.220 回答
0

我在http://www.artima.com/suiterunner/privateP.html找到了一篇关于如何使用 JUNIT 测试私有方法的有趣文章

所以,我认为我们应该更喜欢通过测试公共方法来间接测试私有方法。只有在特殊情况下,我们才应该考虑测试私有方法。

于 2009-01-09T12:44:28.140 回答
0

我认为你应该拆分测试用例。

首先,您测试调用接口的不同实现的类。这意味着您正在测试公共方法。

在此之后,您在另一个测试用例中测试接口实现类。他们可以通过反射调用方法。

于 2009-01-09T11:52:37.653 回答