Following is my code for interfaces, and three classes. I use JUNIT testing and the JUnit test class is also below. However I have no idea to pass the parameters from my concrete classes and use it in JUnit class.
Interface
ArithmeticSkeleton.java
public interface ArithmeticSkeleton {
int operation(int a, int b);
}
Concrete Class For Division
Divide.java
public class Divide implements ArithmeticSkeleton{
@Override
public int operation(int a, int b) {
return (a / b);
}
}
Concrete Class For Multiplication
Multiply.java
public class Multiply implements ArithmeticSkeleton{
@Override
public int operation(int a, int b) {
return (a * b);
}
}
Concrete Class For Addition
Addition.java
public class Addition implements ArithmeticSkeleton{
@Override
public int operation(int a, int b) {
return (a + b);
}
}
JUnit Test Class
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
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?). 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 ). This is not the same as writing all of your tests to a Java interface
type.
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. 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()
. Any of these are correct (if not necessarily ideal) implementations of the Divide
API, and your test should be satisfied with any of them.
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. 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. 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".
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.