답변:
랜덤에 대한 래퍼를 만들어야한다는 전적으로 동의하는 David의 대답을 확장하십시오 . 나는 비슷한 질문 에서 앞서 그것에 대해 거의 같은 대답을 썼 으므로 여기에 "Cliff 's notes version"이 있습니다.
먼저 래퍼를 인터페이스 (또는 추상 클래스)로 작성해야합니다.
public interface IRandomWrapper {
int getInt();
}
이에 대한 구체적인 클래스는 다음과 같습니다.
public RandomWrapper implements IRandomWrapper {
private Random random;
public RandomWrapper() {
random = new Random();
}
public int getInt() {
return random.nextInt(10);
}
}
수업이 다음과 같다고 가정 해보십시오.
class MyClass {
public void doSomething() {
int i=new Random().nextInt(10)
switch(i)
{
//11 case statements
}
}
}
IRandomWrapper를 올바르게 사용하려면 클래스를 수정하여 생성자 또는 설정자를 통해 멤버로 가져와야합니다.
public class MyClass {
private IRandomWrapper random = new RandomWrapper(); // default implementation
public setRandomWrapper(IRandomWrapper random) {
this.random = random;
}
public void doSomething() {
int i = random.getInt();
switch(i)
{
//11 case statements
}
}
}
이제 래퍼를 조롱하여 래퍼로 클래스의 동작을 테스트 할 수 있습니다. 조롱 프레임 워크를 사용 하여이 작업을 수행 할 수 있지만 직접 수행하는 것도 쉽습니다.
public class MockedRandomWrapper implements IRandomWrapper {
private int theInt;
public MockedRandomWrapper(int theInt) {
this.theInt = theInt;
}
public int getInt() {
return theInt;
}
}
당신의 수업은 IRandomWrapper
당신 처럼 보이는 것을 기대하기 때문에 이제는 조롱 한 것을 사용하여 시험에서 행동을 강제 할 수 있습니다. 다음은 JUnit 테스트의 예입니다.
@Test
public void testFirstSwitchStatement() {
MyClass mc = new MyClass();
IRandomWrapper random = new MockedRandomWrapper(0);
mc.setRandomWrapper(random);
mc.doSomething();
// verify the behaviour for when random spits out zero
}
@Test
public void testFirstSwitchStatement() {
MyClass mc = new MyClass();
IRandomWrapper random = new MockedRandomWrapper(1);
mc.setRandomWrapper(random);
mc.doSomething();
// verify the behaviour for when random spits out one
}
도움이 되었기를 바랍니다.
지정된 범위 (0-10)와 지정된 세분성 (정수)이 있습니다. 따라서 테스트 할 때 임의의 숫자로 테스트하지 않습니다. 각 사례에 차례로 맞는 루프 내에서 테스트합니다. case 문을 포함하는 하위 함수에 난수를 전달하면 하위 함수를 테스트 할 수 있습니다.
PowerMock 라이브러리를 사용하여 Random 클래스를 조롱하고 nextInt () 메소드를 스텁하여 예상 값을 리턴 할 수 있습니다. 원하지 않는 경우 원래 코드를 변경할 필요가 없습니다.
PowerMockito를 사용하고 있으며 비슷한 방법을 테스트했습니다. JUnit 테스트를 게시 한 코드는 다음과 같아야합니다.
@RunWith(PowerMockRunner.class)
@PrepareForTest( { Random.class, ClassUsingRandom.class } ) // Don't forget to prepare the Random class! :)
public void ClassUsingRandomTest() {
ClassUsingRandom cur;
Random mockedRandom;
@Before
public void setUp() throws Exception {
mockedRandom = PowerMockito.mock(Random.class);
// Replaces the construction of the Random instance in your code with the mock.
PowerMockito.whenNew(Random.class).withNoArguments().thenReturn(mockedRandom);
cur = new ClassUsingRandom();
}
@Test
public void testSwitchAtZero() {
PowerMockito.doReturn(0).when(mockedRandom).nextInt(10);
cur.doSomething();
// Verify behaviour at case 0
}
@Test
public void testSwitchAtOne() {
PowerMockito.doReturn(1).when(mockedRandom).nextInt(10);
cur.doSomething();
// Verify behaviour at case 1
}
(...)
스위치에서 사례를 더 추가하려는 경우 다음 매개 변수를 수신하기 위해 nextInt (int) 호출을 스텁 할 수도 있습니다.
PowerMockito.doReturn(0).when(mockedRandom).nextInt(Mockito.anyInt());
예쁘지 않나요? :)
QuickCheck를 사용하십시오 ! 나는 최근에 이것을 가지고 놀기 시작했고 놀랍습니다. 대부분의 멋진 아이디어와 마찬가지로 Haskell에서 나온 것이지만 기본 아이디어는 미리 준비된 테스트 케이스를 제공하는 대신 난수 생성기가 대신 빌드 할 수 있다는 것입니다. 그렇게하면 xUnit에서 나타날 수있는 4-6 개의 경우 대신 컴퓨터에서 수백 또는 수천 개의 입력을 시도하고 설정 한 규칙에 맞지 않는 입력을 확인할 수 있습니다.
또한 QuickCheck는 실패 사례를 발견 할 때 실패하여 가장 간단한 사례를 찾을 수 있도록 단순화하려고 시도합니다. (물론 실패한 사례를 찾으면 xUnit 테스트로 빌드 할 수도 있습니다)
Java에는 두 가지 이상의 버전이 있으므로 문제가 없어야합니다.