怎么给java程序建立测试_单元测试-如何在Java应用程序中测试私有构造函数?

在Java中,为了防止误实例化只有静态方法的类,通常会使用私有构造函数。要测试这类私有构造函数,可以利用反射API设置构造函数为可访问并进行调用。测试的主要目的是验证构造函数的私有属性。一种常见做法是在私有构造函数中抛出`UnsupportedOperationException`,然后在测试中捕获该异常以确保构造函数未被非法调用。此外,还可以检查类的构造函数是否确实为私有。
摘要由CSDN通过智能技术生成

单元测试-如何在Java应用程序中测试私有构造函数?

这个问题已经在这里有了答案:

如何为私有构造函数添加测试覆盖率? 18个答案

如果一个类包含一堆静态方法,为了确保没有人错误地初始化该类的实例,我做了一个私有的构造函数:

private Utils() {

}

现在..鉴于无法看到构造函数,该如何进行测试? 可以测试吗?

JAM asked 2020-07-17T08:39:24Z

7个解决方案

68 votes

使用反射,您可以调用私有构造函数:

Constructor c = Utils.class.getDeclaredConstructor();

c.setAccessible(true);

Utils u = c.newInstance(); // Hello sailor

但是,您甚至可以做到这一点:

private Utils() {

throw new UnsupportedOperationException();

}

通过在构造函数中引发异常,可以防止所有尝试。

我也会自己创建类final,只是因为“因为”:

public final class Utils {

private Utils() {

throw new UnsupportedOperationException();

}

}

Bohemian answered 2020-07-17T08:39:50Z

19 votes

测试代码的意图..总是:)

例如:如果看不到构造函数是私有的,那么您需要测试的就是这个事实,仅此而已。

使用反射API查询构造函数,并验证它们是否具有私有属性集。

我会做这样的事情:

@Test()

public void testPrivateConstructors() {

final Constructor>[] constructors = Utils.class.getDeclaredConstructors();

for (Constructor> constructor : constructors) {

assertTrue(Modifier.isPrivate(constructor.getModifiers()));

}

}

如果要对对象构造进行适当的测试,则应该测试公共API,该API允许您获取构造的对象。 这就是上述API应该存在的原因:正确构建对象,因此您应该对此进行测试:)。

Mihai Toader answered 2020-07-17T08:40:28Z

6 votes

@Test

public//

void privateConstructorTest() throws Exception {

final Constructor>[] constructors = Utils.class.getDeclaredConstructors();

// check that all constructors are 'private':

for (final Constructor> constructor : constructors) {

Assert.assertTrue(Modifier.isPrivate(constructor.getModifiers()));

}

// call the private constructor:

constructors[0].setAccessible(true);

constructors[0].newInstance((Object[]) null);

}

MrSmith42 answered 2020-07-17T08:40:46Z

5 votes

确保没有人错误地初始化此类的实例

通常,我要做的是将方法/构造函数从专用更改为默认程序包可见性。 而且我为测试类使用了相同的包,因此即使不是从外部,也可以从测试中访问方法/构造函数。

要强制策略不实例化类,您可以:

从默认的空构造函数中抛出UnsupportedOperationException(“不要实例化此类!”)。

声明类抽象:如果仅包含静态方法,则可以调用静态方法,但不能实例化它,除非您将其子类化。

或同时应用1 + 2,如果测试与目标类共享同一包,则仍可以继承并运行构造函数。这应该是相当“防错的”; 恶意编码人员总会找到解决方法的:)

Luigi R. Viggiano answered 2020-07-17T08:41:29Z

4 votes

如果您有私有构造函数,则从代码的某些非私有方法中调用它。 因此,您测试了该方法,并覆盖了构造函数。 每种方法进行测试没有宗教上的美德。 您正在寻找功能或更佳的分支覆盖级别,并且可以通过在使用该构造函数的代码路径中使用构造函数来简单地获得它。

如果该代码路径比较复杂且难以测试,则可能需要对其进行重构。

bmargulies answered 2020-07-17T08:41:54Z

3 votes

如果在构造函数中添加异常,例如:

private Utils() {

throw new UnsupportedOperationException();

}

在测试类中调用constructor.newInstance()将引发InvocationTargetException而不是UnsupportedOperationException,但是所需的异常将包含在引发的异常中。

如果要断言引发了异常,则可以在捕获到调用异常后引发调用异常的目标。

例如,使用jUnit 4,您可以执行以下操作:

@Test(expected = UnsupportedOperationException.class)

public void utilityClassTest() throws NoSuchMethodException, IllegalAccessException, InstantiationException {

final Constructor constructor = Utils.class.getDeclaredConstructor();

constructor.setAccessible(true);

try {

constructor.newInstance();

} catch (InvocationTargetException e) {

throw (UnsupportedOperationException) e.getTargetException();

}

}

Juan answered 2020-07-17T08:42:28Z

-3 votes

别。 构造函数是私有的。 这就是您所需要的。 Java强制执行其隐私。

不要测试平台。

user207421 answered 2020-07-17T08:42:52Z

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值