代码之家  ›  专栏  ›  技术社区  ›  James

如何使用Mockito模拟@Value类?

  •  0
  • James  · 技术社区  · 4 年前

    我想对以下类进行单元测试:

    @Data
    @AllArgsConstructor
    public class MyClass {
    
       private MyValueClass valueObject;
    
       public BigDecimal someMethod(int startId, int endId) {
    
          List<BigDecimal> values = valueObject.get(startId, endId);
          
          ...
    

    我试着嘲笑 MyValueClass 它看起来像:

    @Value //lombok annotation
    public class MyValueClass {
    
       private List<Data> someData;
    
       public List<BigDecimal> get(int startId, int endId) {
    
           //code to get subset of someData with ids between startId and endId
    
       }
    

    但是当我运行这个junit(jupiter)测试时:

    @ExtendWith(MockitoExtension.class)
    class MyClassTest {
    
       private MyClass myClass;
    
       @Mock
       private MyValueClass valueOjectMock;
    
       @BeforeEach
       public void setUp() {
          myClass= new myClass(valueOjectMock);
       }
    
       @Test
       void test() {
          when(valueOjectMock.get(1,5))
             .thenReturn(new ArrayList<>());
          ....
       }
    }
    

    我得到以下错误:

    org.mockito.exceptions.base.MockitoException: 
    Cannot mock/spy class com.seasset.funds.performance.domain.FundReturns
    Mockito cannot mock/spy because :
     - final class
        at org.mockito.junit.jupiter.MockitoExtension.beforeEach(MockitoExtension.java:153)
    

    但是 MyValueClass 不是最终的。为什么会出现此错误?我怎么能嘲笑这门课?

    0 回复  |  直到 4 年前
        1
  •  3
  •   EricSchaefer    4 年前

    值对象永远不应该被嘲笑。毕竟,它只是一个不可变的值(这就是lombok使其成为最终值的原因)。如果它包含复杂的逻辑或隐藏的可变状态(因此不是实值对象),则不应使用 @Value 但使用您需要的单个片段(如 @Getter ).

        2
  •  2
  •   coloma1984    4 年前

    默认情况下,MyValueClass上的Lombok注释@Value使您的类成为最终类: lombok value feature 。如果您使用的是Mockito版本1,则无法模拟最终类: reference answer for mocking final classes .尝试使用PowerMockito或Mockito v2 Mockito内联:如果您使用的是maven:

    <dependency>
        <groupId>org.mockito</groupId>
        <artifactId>mockito-inline</artifactId>
        <version>3.9.0</version>
        <scope>test</scope>
    </dependency>
    

    如果您想继续使用mockito v1进行测试,如果不影响性能,请尝试将@Value替换为@Data。