如何使用 Mockito 模拟 @Value class?
How to mock a @Value class using Mockito?
我想对以下内容进行单元测试 class:
@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
不是最终的。为什么会出现此错误?我怎样才能嘲笑这个 class?
您的 MyValueClass 上的 Lombok 注释 @Value 默认使您的 class 最终:lombok value feature. If you are using Mockito version 1, you cannot mock final classes: reference answer for mocking final classes。尝试使用 PowerMockito 或 Mockito v2 mockito-inline:如果您使用的是 maven:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>3.9.0</version>
<scope>test</scope>
</dependency>
如果您想继续使用 mockito v1 进行测试,请在不影响性能的情况下尝试将 @Value 替换为 @Data。
永远不应模拟值对象。毕竟它只是一个不可变的值(这就是为什么 lombok 将其定为 final 的原因)。如果它包含复杂的逻辑或隐藏的可变状态(因此不是真正的值对象),则不应使用 @Value
而是使用您需要的各个部分(如 @Getter
)。
我想对以下内容进行单元测试 class:
@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
不是最终的。为什么会出现此错误?我怎样才能嘲笑这个 class?
您的 MyValueClass 上的 Lombok 注释 @Value 默认使您的 class 最终:lombok value feature. If you are using Mockito version 1, you cannot mock final classes: reference answer for mocking final classes。尝试使用 PowerMockito 或 Mockito v2 mockito-inline:如果您使用的是 maven:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>3.9.0</version>
<scope>test</scope>
</dependency>
如果您想继续使用 mockito v1 进行测试,请在不影响性能的情况下尝试将 @Value 替换为 @Data。
永远不应模拟值对象。毕竟它只是一个不可变的值(这就是为什么 lombok 将其定为 final 的原因)。如果它包含复杂的逻辑或隐藏的可变状态(因此不是真正的值对象),则不应使用 @Value
而是使用您需要的各个部分(如 @Getter
)。