这种模拟方法的尝试有什么问题吗?

问题描述 投票:0回答:1

在单元测试中,我试图模拟该方法

List<? extends MessageSourceResolvable> getAllErrors()

那是班级的成员

org.springframework.web.method.annotation.HandlerMethodValidationException

我的单元测试课如下

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.context.MessageSourceResolvable;
import org.springframework.validation.FieldError;
import org.springframework.web.method.annotation.HandlerMethodValidationException;

import java.util.List;

import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
public class MethodValidationExceptionHandlerTests {

    @Mock
    private HandlerMethodValidationException validException;

    @InjectMocks
    private MethodValidationExceptionHandler methodValidationExceptionHandler;

    @Test
    void handle_ShouldReturnFieldErrors_IfMessageNotBlank() {
        MessageSourceResolvable fieldError = new FieldError("objectName", "field1", "validation message");
        List<? extends MessageSourceResolvable> fieldErrors = List.of(fieldError);

        // empty list compiles
        when(validException.getAllErrors()).thenReturn(List.of());   

        // list with a single element fails to compile
        when(validException.getAllErrors()).thenReturn(fieldErrors); 
    }
}

如果我提供一个空列表,代码会编译,但如果我提供一个包含单个元素的列表,则会出现此编译错误

error: no suitable method found for thenReturn(MessageSourceResolvable)
        when(validException.getAllErrors()).thenReturn(fieldError);
                                           ^
    method OngoingStubbing.thenReturn(List<CAP#1>) is not applicable
      (argument mismatch; MessageSourceResolvable cannot be converted to List<CAP#1>)
    method OngoingStubbing.thenReturn(List<CAP#1>,List<CAP#1>...) is not applicable
      (argument mismatch; MessageSourceResolvable cannot be converted to List<CAP#1>)
  where CAP#1 is a fresh type-variable:
    CAP#1 extends MessageSourceResolvable from capture of ? extends MessageSourceResolvable
java unit-testing mockito
1个回答
0
投票

您遇到的问题是在测试中尝试模拟

getAllErrors()
的返回时由类型不匹配引起的。具体来说,
getAllErrors()
预计会返回
List<? extends MessageSourceResolvable>
,但您试图传递
List<MessageSourceResolvable>
(特定类型),它与通配符类型不匹配。

解决方案:

您需要确保返回的列表类型与预期类型匹配

List<? extends MessageSourceResolvable>
。在本例中,由于
FieldError
MessageSourceResolvable
的子类,因此您可以将列表转换为适当的通配符类型。

解决此问题的方法如下:

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.context.MessageSourceResolvable;
import org.springframework.validation.FieldError;
import org.springframework.web.method.annotation.HandlerMethodValidationException;

import java.util.List;

import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
public class MethodValidationExceptionHandlerTests {

    @Mock
    private HandlerMethodValidationException validException;

    @InjectMocks
    private MethodValidationExceptionHandler methodValidationExceptionHandler;

    @Test
    void handle_ShouldReturnFieldErrors_IfMessageNotBlank() {
        MessageSourceResolvable fieldError = new FieldError("objectName", "field1", "validation message");
        List<? extends MessageSourceResolvable> fieldErrors = List.of(fieldError);

        // empty list compiles
        when(validException.getAllErrors()).thenReturn(List.of());   

        // Correct approach: casting the list to the correct type
        when(validException.getAllErrors()).thenReturn((List<? extends MessageSourceResolvable>) fieldErrors); 
    }
}

主要变化:

  • 转换列表:在第二个
    when
    语句中,
    fieldErrors
    列表显式转换为
    List<? extends MessageSourceResolvable>
    。这解决了类型不匹配的问题并允许代码编译。
© www.soinside.com 2019 - 2024. All rights reserved.