代码之家  ›  专栏  ›  技术社区  ›  Tim Clemons

使用Mockito模拟具有泛型参数的类

  •  383
  • Tim Clemons  · 技术社区  · 16 年前

    Foo<T> Foo<Bar>

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

    假设 getValue() T 。但是,当我稍后将其传递给一种方法时,它就会有问题 Foo<酒吧>

    12 回复  |  直到 16 年前
        1
  •  322
  •   osundblad    7 年前

    我认为你确实需要投它,但它不应该太糟糕:

    Foo<Bar> mockFoo = (Foo<Bar>) mock(Foo.class);
    when(mockFoo.getValue()).thenReturn(new Bar());
    
        2
  •  308
  •   Siddhant Saraf Marek Kirejczyk    5 年前

    @Mock 并非在所有情况下都有效,但看起来更性感:)

    @RunWith(MockitoJUnitRunner.class)
    public class FooTests {
    
        @Mock
        public Foo<Bar> fooMock;
        
        @Test
        public void testFoo() {
            when(fooMock.getValue()).thenReturn(new Bar());
        }
    }
    

    这 MockitoJUnitRunner @Mock .

        3
  •  52
  •   null    8 年前

    private interface FooBar extends Foo<Bar>
    {
    }
    

    非最终 类,您可以使用以下代码扩展类并执行相同的操作:

    public class FooBar extends Foo<Bar>
    {
    }
    

    然后,您可以使用以下代码使用上述示例中的任何一个:

    Foo<Bar> mockFoo = mock(FooBar.class);
    when(mockFoo.getValue()).thenReturn(new Bar());
    
        4
  •  18
  •   acdcjunior Mukul Kumar    11 年前

    @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);
    }
    
        5
  •  11
  •   Tobias Uhmann    7 年前

    我同意不应该在类或方法中隐藏警告,因为人们可能会忽视其他意外隐藏的警告。但依我之见,抑制只影响一行代码的警告是绝对合理的。

    @SuppressWarnings("unchecked")
    Foo<Bar> mockFoo = mock(Foo.class);
    
        6
  •  6
  •   M. Justin Marwan Alsabbagh    5 年前

    package com.vogella.junit5;                                                                    
                                                                                                   
    import static org.hamcrest.MatcherAssert.assertThat;                                           
    import static org.hamcrest.Matchers.hasItem;                                                   
    import static org.mockito.Mockito.verify;                                                      
                                                                                                   
    import java.util.Arrays;                                                                       
    import java.util.List;                                                                         
                                                                                                   
    import org.junit.jupiter.api.Test;                                                             
    import org.junit.jupiter.api.extension.ExtendWith;                                             
    import org.mockito.ArgumentCaptor;                                                             
    import org.mockito.Captor;                                                                     
    import org.mockito.Mock;                                                                       
    import org.mockito.junit.jupiter.MockitoExtension;                                             
                                                                                                   
    @ExtendWith(MockitoExtension.class)                                                            
    public class MockitoArgumentCaptureTest {                                                      
                                                                                                   
                                                                                                   
        @Captor                                                                                    
        private ArgumentCaptor<List<String>> captor;                                               
                                                                                                   
        @Test                                                                                      
        public final void shouldContainCertainListItem(@Mock List<String> mockedList) {            
            var asList = Arrays.asList("someElement_test", "someElement");                         
            mockedList.addAll(asList);                                                             
                                                                                                   
            verify(mockedList).addAll(captor.capture());                                           
            List<String> capturedArgument = captor.getValue();                                     
            assertThat(capturedArgument, hasItem("someElement"));                                  
        }                                                                                          
    }                                                                                              
                                                                                                  
    

    https://www.vogella.com/tutorials/Mockito/article.html 对于所需的Maven/Gradle依赖关系。

        7
  •  3
  •   qza    11 年前

    mock() & spy() 方法直接使用,无需不安全的泛型访问和/或抑制泛型警告。

    Mockito项目目前存在一个未决问题( #1531 & 没有泛型警告的方法。该问题于2018年11月公开,但没有任何迹象表明它将被优先处理。根据Mockito撰稿人对此问题的评论:

    鉴于 .class 与泛型配合不好,我认为我们在Mockito中无法找到任何解决方案。你已经可以了 @Mock (JUnit5扩展还允许方法参数 @Mock @Mock 是一个更好的API。

        8
  •  1
  •   vogella    5 年前

    这里有一个有趣的例子:方法接收泛型集合并返回相同基类型的泛型集合。例如:

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

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

    JUnit5 @ExtendWith(MockitoExtension.class)

    @Mock
    Foo<Bar> barMock;
    
        10
  •  0
  •   范仲毠   5 年前

    Foo mockFoo = mock(Foo.class);
    

    1. 使用 @SuppressWarnings("unchecked") 注释。这并不能真正解决问题,但你会停止收到警告。
    @SuppressWarnings("unchecked")
    Foo mockFoo = mock(Foo.class);
    when(mockFoo.getValue).thenReturn(new Bar());
    
    1. 尽管它仍然会发出警告,但不幸的是。因此,您也需要在此处使用注释:
    @SuppressWarnings("unchecked")
    Foo<Bar> mockFoo = (Foo<Bar>) mock(Foo.class);
    when(mockFoo.getValue).thenReturn(new Bar());
    
    1. 使用@Mock注释。不会有任何警告。在这里, when
    @Mock
    public Foo<Bar> fooMock;
    
    @MockBean
    public Foo<Bar> fooMock;