验证没有实例控制的模拟类型的行为

时间:2014-11-07 15:17:31

标签: java unit-testing junit mocking

我正在为内部目的开发JUnit的自定义运行器,例如,我已经为测试方法引入了自定义注释,在应用时应该让我的运行者在所有其他测试方法之后使用此注释运行方法没有这个注释。

我想编写junit test来验证自定义运行器的行为。

测试类:

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()
    }
}

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

1 个答案:

答案 0 :(得分:1)

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

更好的解决方案

使用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"));
  }
}