有没有办法在测试套件 类 之间共享 @Before 代码?

Is there a way to share @Before code between tests suite classes?

我正在 Java/Android 中测试一个 Cordova 插件,我需要初始化我的插件 class 并在我 运行 我的测试之前设置一些状态。

  @Before
  public void beforeEach() throws Exception {
    System.out.println("Creating new Instance ");

    PowerMockito.mockStatic(Helpers.class);
    PowerMockito.when(Helpers.canUseStorage(any(), any())).thenReturn(true);

    MyLogger myLoggerMock = PowerMockito.mock(MyLogger.class);
    PowerMockito.doNothing().when(myLoggerMock, "log", anyString());

    PowerMockito.whenNew(MyLogger.class).withAnyArguments().thenReturn(myLoggerMock);

    this.sut = spy(new FilePicker());
    PowerMockito.doNothing().when(this.sut).pick(any(), any());
  }

我想为每个 public 函数创建一个测试套件/Java Class,但我不想每次都重复该代码。

有没有办法在每个测试套件之间共享?我找到了 ClassRule 但我认为我没有做我需要的(或者我理解错了......我真的是 Java 的新手)

在 Typescript 中,我们可以与多个套件共享 beforeEach 函数,每个套件可以有自己的 beforeEach

一种可能的方法是使用继承:

使所有测试 class 都从一个 "parent test" class 扩展,并在父 class 中定义一个 @Before。 所以它会自动调用所有子classes:

     public class ParentTest {

         @Before
         public void doInitialization() {
          ....
         }
     }

     public class Test1Class extends ParentClass {

         @Test
         public void fooTest() {
          // doInitialization will be executed before this method
         }

         @Test  
         public void barTest() {
           // doInitialization will be executed before this method as well
         }
     }

两个注意事项:

注一

在您使用 sut 的代码中(被测对象)- 这显然不应该在父级的 doInitialization 方法中,因此 Test1Class 也可能有方法注释使用 @Before(阅读 here 了解有关订购等的信息) 然后 `sut 被 Spy 初始化,坦率地说这很奇怪恕我直言,被测主题应该是你写的真实 class ,但这超出了问题的范围,只是提到它因为它可能会指出错误。

注2

我写这篇文章是为了提供帮助,因为你说你是 Java 的新手,这与你的问题没有严格的关系...

虽然这种方法通常有效,但您应该非常谨慎地使用 PowerMockito。我不是 PowerMockito 专家,并尽量避免在我的代码中使用这种类型的模拟,但简而言之,它处理字节码的方式可能会与其他工具发生冲突。从您的代码中:您可以将 HelperUtils 重构为非静态的,从而避免 PowerMocking 以支持更快、更安全的常规模拟。 至于日志——通常你可以在单元测试中妥协,如果你使用 slf4j 库,你可以将它配置为使用 "no-op" 日志进行测试,比如将所有日志消息发送到 "nothing",并且在控制台中看不到它们。