문제

일반 매개 변수로 클래스를 조롱하는 깨끗한 방법이 있습니까? 수업을 조롱해야한다고 가정 해 봅시다 Foo<T> 예상되는 방법으로 전달해야합니다. Foo<Bar>. 다음을 충분히 쉽게 할 수 있습니다.

Foo mockFoo = mock(Foo.class);
when(mockFoo.getValue).thenReturn(new Bar());

가정합니다 getValue() 일반 유형을 반환합니다 T. 하지만 나중에 내가 그것을 기대하는 방법으로 전달할 때 새끼 고양이가있을 것입니다. Foo<Bar>. 캐스트가 이것을하는 유일한 수단인가?

도움이 되었습니까?

해결책

나는 당신이 그것을 캐스팅해야한다고 생각하지만 너무 나쁘지 않아야합니다.

Foo<Bar> mockFoo = (Foo<Bar>) mock(Foo.class);
when(mockFoo.getValue).thenReturn(new Bar());

다른 팁

이 주위의 또 다른 방법은 사용하는 것입니다 @Mock 대신 주석. 모든 경우에 작동하지는 않지만 훨씬 더 섹시 해 보입니다 :)

예는 다음과 같습니다.

@RunWith(MockitoJUnitRunner.class)
public class FooTests {

    @Mock
    public Foo<Bar> fooMock;

    @Test
    public void testFoo() {
        when(fooMock.getValue()).thenReturn(new Bar());
    }
}

그만큼 MockitoJUnitRunner 주석이 달린 필드를 초기화합니다 @Mock.

지정하려는 일반 유형을 만족시키는 중간 클래스/인터페이스를 항상 만들 수 있습니다. 예를 들어 FOO가 인터페이스 인 경우 테스트 클래스에서 다음 인터페이스를 만들 수 있습니다.

private interface FooBar extends Foo<Bar>
{
}

foo가 a 비정기 클래스, 당신은 다음 코드로 클래스를 확장하고 같은 일을 할 수 있습니다.

public class FooBar extends Foo<Bar>
{
}

그런 다음 위의 예제 중 하나를 다음 코드로 소비 할 수 있습니다.

Foo<Bar> mockFoo = mock(FooBar.class);
when(mockFoo.getValue()).thenReturn(new Bar());

a 테스트 유틸리티 방법. 두 번 이상 필요한 경우 특별히 유용합니다.

@Test
public void testMyTest() {
    // ...
    Foo<Bar> mockFooBar = mockFoo();
    when(mockFooBar.getValue).thenReturn(new Bar());

    Foo<Baz> mockFooBaz = mockFoo();
    when(mockFooBaz.getValue).thenReturn(new Baz());

    Foo<Qux> mockFooQux = mockFoo();
    when(mockFooQux.getValue).thenReturn(new Qux());
    // ...
}

@SuppressWarnings("unchecked") // still needed :( but just once :)
private <T> Foo<T> mockFoo() {
    return mock(Foo.class);
}

흥미로운 사례는 다음과 같습니다. 메소드는 일반 모음을 수신하고 동일한 기본 유형의 일반 모음을 반환합니다. 예를 들어:

Collection<? extends Assertion> map(Collection<? extends Assertion> assertions);

이 방법은 Mockito anycollection의 조합과 답변으로 조롱 할 수 있습니다.

when(mockedObject.map(anyCollectionOf(Assertion.class))).thenAnswer(
     new Answer<Collection<Assertion>>() {
         @Override
         public Collection<Assertion> answer(InvocationOnMock invocation) throws Throwable {
             return new ArrayList<Assertion>();
         }
     });

나는 다른 사람이 실수로 억압 된 경고를 간과 할 수 있으므로 수업이나 방법의 경고를 억제해서는 안된다는 데 동의합니다. 그러나 IMHO 단일 줄의 코드에만 영향을 미치는 경고를 억제하는 것이 절대적으로 합리적입니다.

@SuppressWarnings("unchecked")
Foo<Bar> mockFoo = mock(Foo.class);
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top