JUnit 测试抛出@httpStatus 的自定义异常

JUnit test Custom exception that throws @httpStatus

我想测试当我调用这样的方法时我的自定义异常是否被抛出:

private MyObject queryDatabase(String request, String end){
    HttpEntity myEntity = new NStringEntity(request, ContentType.APPLICATION_JSON)
    Response response = restClient.performRequest("GET", end,Collections.emptyMap(), myEntity)

    MyObject myObject = mapper.readValue(response.getEntity().getContent(), MyObject.Class);
    if(myObject.getFunctions().isEmpty()){
        throw new EmptyResultException("Empty result");
    }
    return myObject;
}

我的 EmptyResultException Class :

@ResponseStatus(value=HttpStatus.NO_CONTENT)
public Class EmptyResultException() extends RuntimeException(){
    ...
}

我刚开始使用 JUnit,我已经尝试过了:

@Mock MyService myservice;

@Test(expected=EmptyResultException.class)
public void shouldReturnException() {
    when(myService.queryDatabase(anyString(),anyString())).thenReturn(new MyObject());
}

它不起作用。我想尝试的行为是 private 方法。看来我应该在这种情况下使用 Powermock。但是,我读到测试 private 方法不好,所以我想将我的方法更改为 public。有什么帮助吗?

编辑:我的完整实施:

我有一个 Restcontroller :

@RestController
@RequestMapping...
public class MyController {

    @Autowired 
    MyService myService;

    @RequestMapping...
    public MyObject findObject(@Valid DtoParameters parameters){
      return myService.executeQuery(parameters);
   }
   }

在我的服务中 Class :

@Service
public class MyService{

public MyObject executeQuery(DtoParameters parameters){
 return 
    queryDatabase(parameters.buildRequest(),parameters.buildEnd());

}
}

如果你的 class 被测是 MyService,它不应该有 @Mock

我不知道你的整个实现,但我们假设 MyService 已经注入依赖项(比如你的 mapper

首先我会模拟映射器并将其注入 MyService:

@Mock
private ObjectMapper mapper;

@InjectMocks
private MyService myService;

为此,您的测试 class 需要使用 mockito runner。你可以用这个注释你的class:

@RunWith(MockitoJUnitRunner.class)

模拟将被注入到 MyService 中。 现在你可以模拟你的映射器到 return 一个空对象:

when(mapper.readValue(any(),any())).thenReturn(new MyObject());
myService.queryDatabase("request", "end")

调用queryDatabase时,这个应该调用里面的mock。

如果你想测试你的休息控制器,这是一种不同的方式。我建议的是对 MyService 进行单元测试。如果你想测试控制器,你应该使用 SpringRunnerSpringBootTestMockMvc。但首先,对您的服务进行单元测试,然后在您的控制器上添加其他测试。对于控制器,您可以用 @MockBean 注释 MyService 并抛出,或者 Autowire 它和 @MockBean 里面的映射器到 return 一个像单元测试这样的空对象。

检查这个:https://spring.io/guides/gs/testing-web/


旧答案:

您可以将您的方法更改为 protected,假设您的测试与您正在测试的 class 在同一个包中,您将能够模拟它。

要模拟你的方法,你需要这样写:

when(myService.queryDatabase(anyString(),anyString())).thenThrow(EmptyResultException.class);

您忘记使用 when 方法来结束调用。