java - 在没有实例控制的情况下验证模拟类型的行为

标签 java unit-testing junit mocking

我正在出于内部目的开发 JUnit 的自定义运行程序,例如,我为测试方法引入了自定义注释,应用该注释后,我的运行程序应在没有此注释的所有其他测试方法之后运行带有此注释的方法。

我想编写 junit 测试来验证我的自定义运行程序的行为。

测试类:

public class TestClass {
    @Test
    @CustomAnnotation
    public void test1() {
        System.out.println("test1");
    }

    @Test
    public void test2() {
       System.out.println("test2");
    }
}

将测试我的运行者的抽象代码:

public class MyCustomRunnerTest {
    @Test
    public void order() throws InitializationError {
        // Arrange
        // Some code of mocking library might be placed here

        // Act
        MyCustomRunner runner = new MyCustomRunner(TestClass.class);
        runner.run(new RunNotifier());

        // Assert
        // Here I want to verify that method test1() has been called
        // after method test2()
    }
}

是否有任何模拟库可以让我执行此类验证?或者可能有其他方法可以检查吗?

最佳答案

为什么不将决定测试方法运行顺序的逻辑提取到单独的类或方法中?此方法应返回测试方法名称(或其他描述符)的列表,按照它们运行的​​顺序。然后,您的测试将归结为向其传递测试类并断言输出为 { "test2", "test1"}。不需要 mock 。

更好的解决方案

使用 RunListener 记录运行程序正在运行的测试方法。您当然将拥有自己的 MyCustomRunner 类,但其余代码可以保留如下例所示:

import static org.hamcrest.Matchers.contains;
import static org.junit.Assert.assertThat;

import java.util.ArrayList;
import java.util.Collection;

import org.junit.Test;
import org.junit.runner.Description;
import org.junit.runner.RunWith;
import org.junit.runner.notification.RunListener;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.InitializationError;

@RunWith(BlockJUnit4ClassRunner.class)
public class RunnerTest {
  // dummy "custom" test runner
  public static class MyCustomRunner extends BlockJUnit4ClassRunner {
    public MyCustomRunner(Class<?> klass) throws InitializationError {
      super(klass);
    }
  }

  public static class TestClass {
    @Test
    public void test1() {}

    @Test
    public void test2() {}
  }

  @Test
  public void myCustomRunnerExecutesTestsInOrder() throws InitializationError {
    RunNotifier notifier = new RunNotifier();
    Collection<String> runTestMethods = new ArrayList<>();
    notifier.addListener(new RunListener() {
      @Override
      public void testStarted(Description description) throws Exception {
        runTestMethods.add(description.getMethodName());
      }
    });

    new MyCustomRunner(TestClass.class).run(notifier);
    // assert that the collection contains methods names in the specified order
    assertThat(runTestMethods, contains("test1", "test2"));
  }
}

关于java - 在没有实例控制的情况下验证模拟类型的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26804341/

相关文章:

java - 哪个类用于写入字符而不是字节?

java - 良好的 Java 属性文件编辑器

java - TestContainers 框架无法访问 docker 守护进程

ios - 使用 NSURLSession 进行单元测试

java - DBUnit,使用带有注释配置的DTD

java - 使用 @mock 进行模拟将变为 null

java - 将 .java 文件导入 Netbeans 中的 Java 项目

Java:如果多个线程尝试访问从 LinkedList 而不是 ConcurrentLinkedQueue 实现的队列,会发生什么情况?

php - 无法断言 PHPUnit 中的参数类型

c# - 使用 Mock IDbSet 对 Entity Framework 进行单元测试