Java 为什么这不是使用Junit的参数化数据对同步方法进行单元测试?
我正在尝试学习JUnit,并希望以多线程的方式将其扩展到测试中。Java 为什么这不是使用Junit的参数化数据对同步方法进行单元测试?,java,multithreading,unit-testing,junit,parameterized-unit-test,Java,Multithreading,Unit Testing,Junit,Parameterized Unit Test,我正在尝试学习JUnit,并希望以多线程的方式将其扩展到测试中。 我想测试的类是PrimeNumberValidator。这只是测试传入的数字是否为素数 package com; public class PrimeNumberValidator { public Boolean validate(final Integer primeNumber) { System.out.println("Validating .............:" + primeNumb
我想测试的类是PrimeNumberValidator。这只是测试传入的数字是否为素数
package com;
public class PrimeNumberValidator {
public Boolean validate(final Integer primeNumber) {
System.out.println("Validating .............:" + primeNumber);
for (int i = 2; i < (primeNumber / 2); i++) {
if (primeNumber % i == 0) {
return false;
}
}
return true;
}
}
package-com;
公共类PrimeNumberValidator{
公共布尔验证(最终整数素数){
System.out.println(“验证………:”+素数);
对于(int i=2;i<(素数/2);i++){
if(素数%i==0){
返回false;
}
}
返回true;
}
}
PrimeNumberValidatorTest是测试类。测试数据中的2个是错误的,我这样做是为了测试失败
测试方法testPrimeNumberValidator运行良好。但是,多线程版本的testMultiThreadedPrimeNumberValidator总是对错误的数据说“通过”。
为什么会这样
如何解决这个问题?
package com;
import static org.junit.Assert.assertEquals;
import java.util.Arrays;
import java.util.Collection;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@RunWith(Parameterized.class)
public class PrimeNumberValidatorTest {
private Integer primeNumber;
private Boolean expectedValidation;
private PrimeNumberValidator primeNumberValidator;
@Before
public void initialize() {
primeNumberValidator = new PrimeNumberValidator();
}
// Each parameter should be placed as an argument here
// Every time runner triggers, it will pass the arguments from parameters we defined
public PrimeNumberValidatorTest(Integer primeNumber, Boolean expectedValidation) {
this.primeNumber = primeNumber;
this.expectedValidation = expectedValidation;
}
@Parameterized.Parameters
public static Collection primeNumbers() {
return Arrays.asList(new Object[][] {
{ 2, Boolean.FALSE},// 2 is prime so Test should fail
{ 6, Boolean.FALSE}, //is NOT prime so test should pass
{ 19, Boolean.TRUE},//is prime so test should pass
{ 22, Boolean.TRUE} //is NOT prime so test should fail
});
}
// This test will run 4 times since we have 4 parameters defined
@Test
public void testPrimeNumberValidator() {
assertEquals(expectedValidation, primeNumberValidator.validate(primeNumber));
}
@Test
public void testMultiThreadedPrimeNumberValidator() {
ExecutorService executor = Executors.newFixedThreadPool(100);
executor.submit(new Runnable() {
public void run() {
for (int i = 0; i < 100; i++) {
assertEquals(expectedValidation, primeNumberValidator.validate(primeNumber));
}
}
});
}
}
package-com;
导入静态org.junit.Assert.assertEquals;
导入java.util.array;
导入java.util.Collection;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
导入org.junit.Before;
导入org.junit.Ignore;
导入org.junit.Test;
导入org.junit.runner.RunWith;
导入org.junit.runners.Parameterized;
@RunWith(参数化的.class)
公共类PrimeNumberValidatorTest{
私有整数素数;
私有布尔期望验证;
私有PrimeNumberValidator PrimeNumberValidator;
@以前
公共无效初始化(){
primeNumberValidator=新primeNumberValidator();
}
//每个参数都应该放在这里作为参数
//每次运行程序触发时,它都会传递我们定义的参数的参数
公共PrimeNumberValidatorTest(整数primeNumber,布尔期望验证){
this.primeNumber=primeNumber;
this.expectedValidation=expectedValidation;
}
@参数化。参数化
公共静态集合素数(){
返回Arrays.asList(新对象[][]{
{2,Boolean.FALSE},//2是素数,所以测试应该失败
{6,Boolean.FALSE},//不是素数,所以测试应该通过
{19,Boolean.TRUE},//是素数,所以测试应该通过
{22,Boolean.TRUE}//不是素数,所以测试应该失败
});
}
//这个测试将运行4次,因为我们定义了4个参数
@试验
public void testPrimeNumberValidator(){
assertEquals(expectedValidation,primeNumberValidator.validate(primeNumber));
}
@试验
public void testmulti-threadedPrimeNumberValidator(){
ExecutorService executor=Executors.newFixedThreadPool(100);
执行者提交(新的可运行(){
公开募捐{
对于(int i=0;i<100;i++){
assertEquals(expectedValidation,primeNumberValidator.validate(primeNumber));
}
}
});
}
}
参考一篇文章中提到的,尝试如下
会抛出异常,但JUnit不会报告失败:(
package-com;
导入静态org.junit.Assert.assertEquals;
导入java.util.array;
导入java.util.Collection;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
导入org.junit.After;
导入org.junit.Before;
导入org.junit.Ignore;
导入org.junit.Test;
导入org.junit.runner.RunWith;
导入org.junit.runners.Parameterized;
@RunWith(参数化的.class)
公共类PrimeNumberValidatorTest{
易失性异常;
波动误差;
私有整数素数;
私有布尔期望验证;
私有PrimeNumberValidator PrimeNumberValidator;
@以前
公共无效初始化(){
primeNumberValidator=新primeNumberValidator();
}
//每个参数都应该放在这里作为参数
//每次运行程序触发时,它都会传递我们定义的参数的参数
公共PrimeNumberValidatorTest(整数primeNumber,布尔期望验证){
this.primeNumber=primeNumber;
this.expectedValidation=expectedValidation;
}
@参数化。参数化
公共静态集合素数(){
返回Arrays.asList(新对象[][]{
{2,Boolean.FALSE},//2是素数,所以测试应该失败
{6,Boolean.FALSE},//不是素数,所以测试应该通过
{19,Boolean.TRUE},//是素数,所以测试应该通过
{22,Boolean.TRUE}//不是素数,所以测试应该失败
});
}
//这个测试将运行4次,因为我们定义了4个参数
@试验
@忽略
public void testPrimeNumberValidator(){
assertEquals(expectedValidation,primeNumberValidator.validate(primeNumber));
}
@试验
public void testmulti-threadedPrimeNumberValidator(){
ExecutorService executor=Executors.newFixedThreadPool(100);
执行者提交(新的可运行(){
公开募捐{
对于(int i=0;i<1;i++){
试一试{
assertEquals(expectedValidation,primeNumberValidator.validate(primeNumber));
}捕获(错误e){
System.out.println(“抛出错误:“+e”);
误差=e;
}捕获(例外e){
例外=e;
System.out.println(“抛出异常:”+e);
}
}
}
});
}
@之后
public void runAfterEveryTest()引发异常{
如果(null!=错误){
System.out.println(“runAfterEveryTest抛出错误…………”;
投掷误差;
}
if(null!=异常){
System.out.println(“runAfterEveryTest抛出异常…………”;
抛出异常;
}
}
}
多线程始终通过的原因如下:
- 首先,测试方法不会等待多个线程完成
package com; import static org.junit.Assert.assertEquals; import java.util.Arrays; import java.util.Collection; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import org.junit.After; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @RunWith(Parameterized.class) public class PrimeNumberValidatorTest { volatile Exception exception; volatile Error error; private Integer primeNumber; private Boolean expectedValidation; private PrimeNumberValidator primeNumberValidator; @Before public void initialize() { primeNumberValidator = new PrimeNumberValidator(); } // Each parameter should be placed as an argument here // Every time runner triggers, it will pass the arguments from parameters we defined public PrimeNumberValidatorTest(Integer primeNumber, Boolean expectedValidation) { this.primeNumber = primeNumber; this.expectedValidation = expectedValidation; } @Parameterized.Parameters public static Collection primeNumbers() { return Arrays.asList(new Object[][] { { 2, Boolean.FALSE},// 2 is prime so Test should fail { 6, Boolean.FALSE}, //is NOT prime so test should pass { 19, Boolean.TRUE},//is prime so test should pass { 22, Boolean.TRUE} //is NOT prime so test should fail }); } // This test will run 4 times since we have 4 parameters defined @Test @Ignore public void testPrimeNumberValidator() { assertEquals(expectedValidation, primeNumberValidator.validate(primeNumber)); } @Test public void testMultiThreadedPrimeNumberValidator() { ExecutorService executor = Executors.newFixedThreadPool(100); executor.submit(new Runnable() { public void run() { for (int i = 0; i < 1; i++) { try{ assertEquals(expectedValidation, primeNumberValidator.validate(primeNumber)); }catch(Error e){ System.out.println("error thrown :" + e); error =e; }catch(Exception e){ exception=e; System.out.println("exception thrown :" + e); } } } }); } @After public void runAfterEveryTest() throws Exception{ if(null != error){ System.out.println("runAfterEveryTest throwing error..............."); throw error; } if(null != exception){ System.out.println("runAfterEveryTest throwing exception..............."); throw exception; } } }
@Test public void testMultiThreadedPrimeNumberValidator() throws InterruptedException, ExecutionException { ExecutorService executor = Executors.newFixedThreadPool(100); Future future = executor.submit(new Runnable() { public void run() { for (int i = 0; i < 10; i++) { try{ assertEquals(expectedValidation, primeNumberValidator.validate(primeNumber)); }catch(Error e){ System.out.println("error thrown :" + e); //error =e; System.out.println("error set to :" + e); }catch(Exception e){ System.out.println("exception thrown :" + e); //exception=e; System.out.println("Exception set to :" + e); } } } }); future.get(); }