java - 使用 jUnit 测试类实现接口(interface)作为模板的设计的正确性

标签 java unit-testing junit interface

我有很多简单的类实现一个简单的接口(interface):

public interface MyInterface<T> {
    public T value();
}

当然,我想为所有这些类创建单元测试。假设类(class)MyClass implements MyInterface<String>以及以下示例:

public class MyClassTest {

    @Test
    public void valueTest() {
        assertEquals(new MyClass(...).value(), ...);
    }

    @Test
    public void performanceTest() {
        assertTimeout(ofMillis(1), () -> new MyClass(...).value());
    }
}
<小时/>

嗯,这种模式会重复很多次,所以应用模板将帮助我简化工作。但是,我认为使用接口(interface)会更好,因为测试类确实必须实现所有方法。

public interface MyInterfaceTestTemplate {
    public void valueTest();
    public void performanceTest();
}

并在单元测试类中实现它:

public class MyClassTest implements MyInterfaceTestTemplate {

    @Test
    @Override
    public void valueTest() {
        assertEquals(new MyClass(...).value(), ...);
    }

    @Test
    @Override
    public void performanceTest() {
        assertTimeout(ofMillis(1), () -> new MyClass(...).value());
    }
}
<小时/>

我的问题是:

  • 这种方法有哪些优点和缺点?
  • 这种方式是否遵循测试驱动开发的思想?
  • 这是检查单元测试有效性的好方法吗?

最佳答案

您可以在代码中使用 Junt5 ( https://blog.codefx.org/libraries/junit-5-parameterized-tests ) 的参数化测试:

@ParameterizedTest
@MethodSource(names = "createInterfaceImplAndCheckValue")
void testValue(MyInterface impl, Object value) { 
    assertEquals(impl.getValue(),value)
}

private static Stream<Arguments> createInterfaceImplAndCheckValue() {
    return Stream.of(
            ObjectArrayArguments.create(new MyInterfaceImpl1(), "hi"),
            ObjectArrayArguments.create(new MyInterfaceImpl2(), 7));
}

@ParameterizedTest
@MethodSource(names = "createInterfaceImplAndTimeout")
void testPerformance(MyInterface impl, int timeout) { 
        assertTimeout(ofMillis(timeout), () -> impl.value());
}

private static Stream<Arguments> createInterfaceImplAndTimeout() {
    return Stream.of(
            ObjectArrayArguments.create(new MyInterfaceImpl1(), 1),
            ObjectArrayArguments.create(new MyInterfaceImpl2(), 13));
}

当然,您也可以将所有内容放入同一个“数据方法”方法中,并忽略不需要的参数:

@ParameterizedTest
@MethodSource(names = "createInterfaceImplAndCheckValue")
void testValue(MyInterface impl, Object value, int timeout) { 
    assertEquals(impl.getValue(),value)
}


@ParameterizedTest
@MethodSource(names = "createInterfaceImplAndCheckValue")
void testPerformance(MyInterface impl, Object value, int timeout) { 
        assertTimeout(ofMillis(timeout), () -> impl.value());
}

private static Stream<Arguments> createInterfaceImplAndCheckValue() {
    return Stream.of(
            ObjectArrayArguments.create(new MyInterfaceImpl1(), "hi", 1),
            ObjectArrayArguments.create(new MyInterfaceImpl2(), 7, 12));
}

关于java - 使用 jUnit 测试类实现接口(interface)作为模板的设计的正确性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48715021/

相关文章:

c# - Singleton 设计模式是否内置于任何框架中?

c++ - 重构 protected 基类依赖以进行测试

java - 在单元测试中模拟注入(inject)字段

java - 如何在单元测试中创建 Bundle

java - 类型不匹配 : cannot convert from Map<Object, Map<Object,List<ActorContents>>> 到 Map<Actor ,Map<String,List<ActorContents>>>

java - 延迟数据导致 OnCreate 上出现 NullPointerException

java - Spring MVC 和 jQuery 自动完成

ios - 在 XCode 单元测试中测试导航

java - 使用 Stream...peek() 创建的变量的测试方法

java - 在所有 JUnit 测试开始运行之前定义变量?