私は JUnit を学習しようとしており、それを拡張してマルチスレッドでテストしたいと考えていました。
テストしたいクラスは 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;
}
}
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));
}
}
});
}
}
http://www.youtube.com/watch?v=wDN_EYUvUq0を参照して
、マルチスレッド環境で JUnit を使用する奇妙な問題の投稿の 1 つに記載されているように、以下のように試しました。
例外はスローされますが、JUnit は失敗を報告しません:(
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;
}
}
}