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 进行单元测试。如果你想测试控制器,你应该使用 SpringRunner
、SpringBootTest
和 MockMvc
。但首先,对您的服务进行单元测试,然后在您的控制器上添加其他测试。对于控制器,您可以用 @MockBean
注释 MyService 并抛出,或者 Autowire
它和 @MockBean
里面的映射器到 return 一个像单元测试这样的空对象。
检查这个:https://spring.io/guides/gs/testing-web/
旧答案:
您可以将您的方法更改为 protected
,假设您的测试与您正在测试的 class 在同一个包中,您将能够模拟它。
要模拟你的方法,你需要这样写:
when(myService.queryDatabase(anyString(),anyString())).thenThrow(EmptyResultException.class);
您忘记使用 when
方法来结束调用。
我想测试当我调用这样的方法时我的自定义异常是否被抛出:
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 进行单元测试。如果你想测试控制器,你应该使用 SpringRunner
、SpringBootTest
和 MockMvc
。但首先,对您的服务进行单元测试,然后在您的控制器上添加其他测试。对于控制器,您可以用 @MockBean
注释 MyService 并抛出,或者 Autowire
它和 @MockBean
里面的映射器到 return 一个像单元测试这样的空对象。
检查这个:https://spring.io/guides/gs/testing-web/
旧答案:
您可以将您的方法更改为 protected
,假设您的测试与您正在测试的 class 在同一个包中,您将能够模拟它。
要模拟你的方法,你需要这样写:
when(myService.queryDatabase(anyString(),anyString())).thenThrow(EmptyResultException.class);
您忘记使用 when
方法来结束调用。