简体   繁体   English

如何为JUnit中的接口准备测试用例?

[英]How do I prepare test cases for Interfaces in JUnit?

Following is my code for interfaces, and three classes. 以下是我的接口代码和三个类。 I use JUNIT testing and the JUnit test class is also below. 我使用JUNIT测试,JUnit测试类也在下面。 However I have no idea to pass the parameters from my concrete classes and use it in JUnit class. 但是我不知道从我的具体类中传递参数并在JUnit类中使用它。

Interface 接口
ArithmeticSkeleton.java ArithmeticSkeleton.java

public interface ArithmeticSkeleton {
    int operation(int a, int b);
}

Concrete Class For Division 具体科
Divide.java Divide.java

public class Divide implements ArithmeticSkeleton{
    @Override
    public int operation(int a, int b) {
        return (a / b);
    }
}

Concrete Class For Multiplication 乘法的具体类
Multiply.java Multiply.java

public class Multiply implements ArithmeticSkeleton{
    @Override
    public int operation(int a, int b) {
        return (a * b);
    }
}

Concrete Class For Addition 具体的附加类
Addition.java Addition.java

 public class Addition implements ArithmeticSkeleton{
        @Override
        public int operation(int a, int b) {
            return (a + b);
        }
    }

JUnit Test Class JUnit测试类
ArithmeticSkeletonTest.java ArithmeticSkeletonTest.java

import static org.junit.Assert.*;
import java.util.Arrays;
import java.util.Collection;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@RunWith(Parameterized.class)
    public class ArithmeticSkeletonTest {
        public ArithmeticSkeleton asInterface;
        public Divide div;
        public ArithmeticSkeletonTest(ArithmeticSkeleton asInterface) {
            this.asInterface = asInterface;
    }
    @Parameterized.Parameters
    public static Collection<Object[]> testInstances(){
        return Arrays.asList(
                new Object[]{new Multiply()},
                new Object[]{new Addition()},
                new Object[]{new Subtraction()},
                new Object[]{new Divide()}
               );
    }   
}

how to test it on ArithmeticSkeletonTest.java 如何在ArithmeticSkeletonTest.java上对其进行测试

You don't test interfaces, you test implementations. 您不测试接口,而是测试实现。 In this case, the only contract you have for your interface is that it provide the function (int a, int b) -> int , with nothing more specific stated (in particular, is it okay for b to be zero?). 在这种情况下,您接口的唯一约定是它提供函数(int a, int b) -> int ,没有更具体的说明(特别是b可以为零吗?)。 The compiler ensures that this contract is upheld. 编译器确保遵守此合同。

Instead, you should write a test for each implementing class , verifying that it performs the operation as expected. 相反,您应该为每个实现类编写一个测试,以验证它是否按预期执行了该操作。

Writers will sometimes say that you should test interfaces and not implementations. 作家有时会说您应该测试接口而不是实现。 What they mean is that your test should interact with the API or contract, also known as the public interface of your code ( black-box testing ), and not examine the internal state of the class under test ( white-box testing ). 它们的意思是您的测试应该与API或协定(也称为代码的公共接口)交互黑盒测试 ),而不检查被测类的内部状态( 白盒测试 )。 This is not the same as writing all of your tests to a Java interface type. 这与将所有测试写入Java interface类型不同。

For example, the contract of your Divide class says that it should return the quotient of a divided by b , and your test cases should confirm that this is what happens. 例如,您的Divide类的合同规定应返回a除以b的商,而您的测试用例应确认会发生这种情况。 However, it's up to your class to decide how to implement that. 但是,这取决于您的班级来决定如何实现。 You can use the / operator, but you could also perform iterated subtraction, or you could use BigInteger.divide() . 您可以使用/运算符,但也可以执行迭代减法,或者可以使用BigInteger.divide() Any of these are correct (if not necessarily ideal) implementations of the Divide API, and your test should be satisfied with any of them. 这些方法中的任何一个都是Divide API的正确(如果不一定是理想的)实现,并且您对其中的任何一个都应该感到满意。

You don't test interfaces, you test implementations. 您不测试接口,而是测试实现。 So if you have 5 classes that implement an interface, you will need 5 test classes, one for each implementation. 因此,如果您有5个实现接口的类,则将需要5个测试类,每个实现一个。 You will find that those 5 classes have much code in common, because all will test that the implementations conform to the contract of the interface. 您会发现这5个类有很多相同的代码,因为所有这些类都将测试实现是否符合接口协定。 I find it useful to extract that common code into parametric tests in a "test" class for the interface. 我发现将通用代码提取到接口的“测试”类中的参数测试中很有用。 It does not really "test the interface"; 它并不是真正的“测试接口”; it tests "classes that implement the interface". 它测试“实现接口的类”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM