Mockito Matcher for a TypeReference



我正在尝试使用Mockito编写Java单元测试,但是无法使匹配器工作。

我想测试以下类

定制服务.java

public class CustomService {
private final ApplicationProperties props;
public CustomService(ApplicationProperties props){
this.props = props;
}
private final ObjectMapper mapper = new ObjectMapper();
public void method(JsonNode message) throws CustomException {
try {
List<String> actions = mapper.readValue(message.get("actions").toString(), mapper.getTypeFactory().constructCollectionType(List.class, String.class));
System.out.println(actions);
} catch (IOException ex){
throw new CustomException(ex);
}
}
}

我有一个自定义异常类

自定义例外.java

@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
public class CustomException extends Exception {
public CustomException(Throwable cause) {
super(cause);
}
}

我想测试是否抛出自定义异常。 我正在使用莫克托。 我已经尝试了下面的方法,但给定的语句似乎没有在方法中获取(readValue(代码行

定制服务测试.java

public class CustomServiceTest {
private final ApplicationProperties props = mock(ApplicationProperties.class);
private final CustomService customService = new CustomService(props);
private static final ObjectMapper objectMapper = new ObjectMapper();
@Test
public void CustomExceptionIsThrown() throws Exception {
ObjectMapper mapper = mock(ObjectMapper.class);
given(mapper.readValue(anyString(), any(TypeReference.class))).willThrow(new IOException("This is a test"));
String json = "{"actions":["ac1","ac2","ac3","ac4"]}";
JsonNode d = objectMapper.readTree(json);
assertThrows(CustomException.class, () ->
customService.method(d));
}
}

运行测试时出现以下错误

Expected exception.CustomException to be thrown, but nothing was thrown..

帮助将不胜感激。

我也遇到了同样的问题,我发现虽然我像"when(objectMapper.readValue(anyString((, any(TypeReference.class(((.thenReturn(xxxx(;"但是当我调用测试时,readValue(xx,xx( 的第一个参数为null,它应该是一个字符串对象。因此,您可能需要再次检查 readValue 方法输入参数。希望它会有所帮助。

您的示例代码仍然存在一些问题。

  • 您没有将ObjectMapper模拟注入CustomService课。

  • 由于您正在测试的类现在具有 args 构造函数,因此您将无法将模拟注入到测试中。您需要调整构造函数以从外部传递ObjectMapper或依靠Reflections手动放置模拟。

一般建议是将ObjectMapper作为论据传递给解释者。这样做,您无需更改字段mapper上的final

private final ApplicationProperties props;
private final ObjectMapper mapper;
public CustomService(ApplicationProperties props, ObjectMapper mapper){
this.props = props;
this.mapper = mapper;
}
  • 您仍未定义调用getTypeFactory()方法时模拟的行为。此时你应该得到一个NullPointerException(如果你的代码实际上使用了那个模拟(。
    在下面的示例中,我使用RETURNS_DEEP_STUBS选项替换了此定义, 这导致mapper.getTypeFactory().constructCollectionType(List.class, String.class)返回CollectionType的模拟。

  • 不需要带有TypeReference的模拟定义,因为它与调用readValue方法时使用的方法参数不匹配。相反,您将不得不使用CollectionType.

  • 由于测试的方法void因此必须改用willThrow(...).given(...)语法。


这里有一个工作测试的例子:
(仅适用于具有no-args构造函数的CustomService类(

@ExtendWith(MockitoExtension.class)
public class JacksonTest {
static class CustomException extends Exception {
public CustomException(IOException ex) {
super(ex);
}
}
static class CustomService { 
private ObjectMapper mapper = new ObjectMapper();
public void method(String c) throws CustomException {       
try {
mapper.readValue(c, mapper.getTypeFactory().constructCollectionType(List.class, String.class));            
} catch (IOException ex){
throw new CustomException(ex);
}
}
}
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
ObjectMapper mapper;
@InjectMocks
CustomService customService;
@Test
public void testCustomExceptionIsThrown() throws Exception {
BDDMockito.willThrow(new IOException("This is a test")).given(mapper).readValue(ArgumentMatchers.anyString(), ArgumentMatchers.any(CollectionType.class));
Assertions.assertThrows(CustomException.class, () -> customService.method("x")); 
}
}

依赖:

testCompile "org.junit.jupiter:junit-jupiter-api:5.5.2"
testCompile "org.junit.jupiter:junit-jupiter-engine:5.5.2"
testCompile "org.mockito:mockito-core:3.0.0"
testCompile "org.mockito:mockito-junit-jupiter:3.0.0"
compile "com.fasterxml.jackson.core:jackson-databind:2.9.9"

相关内容

  • 没有找到相关文章

最新更新