如何使用VisibleForTesting进行纯JUnit测试

Dan*_*ico 20 java junit android junit4 android-testing

我正在我的项目上运行纯JUnit4 java测试而不是我的纯java文件,但我找不到一种方法来清楚地使用@VisibleForTesting而不会手动公开.

例如:

@VisibleForTesting
public Address getAddress() {
  return mAddress;
}
Run Code Online (Sandbox Code Playgroud)

方法必须是public让它对测试"公开",但在这种情况下,注释没有意义吗?如果注释不会做什么,为什么不只是使用注释?

Mik*_*keJ 37

如果测试在相应的测试包中(与生产代码相同的包名),则使方法包为private,测试将能够看到它.

@VisibleForTesting
Address getAddress() {
  return mAddress;
}
Run Code Online (Sandbox Code Playgroud)

还要考虑重构代码,这样就不需要显式测试私有方法,尝试测试公共接口的行为.难以测试的代码可以表明可以对生产代码进行改进.

注释的要点是它的约定可以用于静态代码分析,而注释则不能.

  • “还可以考虑重构代码,这样就不必显式测试私有方法,而无需测试公共接口的行为。” 不同意这一点。有时您需要通过将一组参数传递给某个类A来进行依赖注入,该类A会从类B创建一些对象。我必须为类B创建一个公共构造函数,因此类A可以直接使用它而不是类B的getInstance()方法。可接受的答案对我有用,我无法将单元测试转移到不同的程序包中以完成此工作。对我来说,这似乎是一种解决方法,可接受的答案更好。 (3认同)

Rod*_*rba 19

根据Android文档:

如果不进行测试,您可以选择指定可见性应该是什么; 这允许工具捕获生产代码中的非预期访问.

例:

@VisibleForTesting(否则= VisibleForTesting.PRIVATE)public Address getAddress()

  • 但是,它确实提高了代码的整体可读性.特别是对于新开发者. (11认同)
  • 默认值已经是私有的,无需指定它. (5认同)

Dan*_*ico 18

标签本身有助于 linter 识别不需要的访问。

为了直接降低使用它的风险,添加此方法是internal科特林protectedJava的,而不是public,并与仅是在同一个包就能访问该方法测试或类。

爪哇:

@VisibleForTesting
protected Address address() {
  return mAddress;
}
Run Code Online (Sandbox Code Playgroud)

科特林:

@VisibleForTesting
internal fun address(): Address {
  return address;
}
Run Code Online (Sandbox Code Playgroud)


小智 10

@VisibleForTesting 注释用于 Guava 中的包方法中,并且不属于 JUnit API 的一部分。注解只是一个标记,表明该方法可以被测试。它甚至没有被加载到 JVM 中。