我正在使用Spring微服务(模块)开发项目,我想使用2016-11-16 15:56:35.418 Projc[43766:2236752] +[UIColor bt_colorWithBytesR:G:B:]: unrecognized selector sent to class 0x10fd17948
2016-11-16 15:56:35.504 Projc[43766:2236752] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[UIColor bt_colorWithBytesR:G:B:]: unrecognized selector sent to class 0x10fd17948'
*** First throw call stack:
(
0 CoreFoundation 0x00000001116aaf45 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x0000000110998deb objc_exception_throw + 48
2 CoreFoundation 0x00000001116b346d +[NSObject(NSObject) doesNotRecognizeSelector:] + 205
3 CoreFoundation 0x0000000111600eea ___forwarding___ + 970
4 CoreFoundation 0x0000000111600a98 _CF_forwarding_prep_0 + 120
5 Projc 0x000000010ccb95b0 -[BTUI borderColor] + 64
6 Projc 0x000000010cc9abf4 -[BTDropInContentView initWithFrame:] + 964
7 UIKit 0x000000010f0abe3d -[UIView init] + 62
8 Projc 0x000000010ccc329e -[BTUIThemedView init] + 62
9 Projc 0x000000010cca5fed -[BTDropInViewController initWithAPIClient:] + 285
10 Projc 0x000000010cb0998b __51-[RegisterController basicPlanClicked]_block_invoke + 411
11 Projc 0x000000010cac1a66 __59-[downloadJson:endPointString:WithHandler:]_block_invoke + 214
12 CFNetwork 0x000000010d4f5b3d __75-[__NSURLSessionLocal taskForClass:request:uploadFile:bodyData:completion:]_block_invoke + 19
13 CFNetwork 0x000000010d507fb6 __49-[__NSCFLocalSessionTask _task_onqueue_didFinish]_block_invoke + 302
14 Foundation 0x000000011060c3b8 __NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK__ + 7
15 Foundation 0x00000001105480e5 -[NSBlockOperation main] + 101
16 Foundation 0x000000011052b036 -[__NSOperationInternal _start:] + 646
17 Foundation 0x000000011052ac47 __NSOQSchedule_f + 194
18 libdispatch.dylib 0x0000000111e0649b _dispatch_client_callout + 8
19 libdispatch.dylib 0x0000000111dee2af _dispatch_main_queue_callback_4CF + 1738
20 CoreFoundation 0x000000011160b2e9 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
21 CoreFoundation 0x00000001115cc8a9 __CFRunLoopRun + 2073
22 CoreFoundation 0x00000001115cbe08 CFRunLoopRunSpecific + 488
23 GraphicsServices 0x0000000112291ad2 GSEventRunModal + 161
24 UIKit 0x000000010f01f30d UIApplicationMain + 171
25 Projc 0x000000010cba86bf main + 111
26 libdyld.dylib 0x0000000111e3b92d start + 1
27 ??? 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
测试我的REST端点。我的测试适用于请求有效但在请求无效的URL时无效的情况。通过不工作我的意思是我的自定义异常处理程序(MockMvc
)没有被调用,抛出异常并且测试失败。
我的异常处理程序和测试类在不同的模块中实现。
common-module(ExceptionHandler)
@ControllerAdvice
国模块
这是我的REST端点和Testing类的实现。公共模块依赖项包含在此模块的pom.xml中,并且通过主类扫描包。
CountryApplication.java
@ControllerAdvice
public class CoreExceptionHandler {
@ExceptionHandler(value = Exception.class)
public ResponseEntity<ErrorMessageDTO> handleException(Exception ex, HttpServletRequest request) {
// Getting servlet request URL
String uri = request.getRequestURI();
HttpStatus a;
ErrorMessageDTO errorMessage;
if (ex instanceof CoreException) {
CoreException e = (CoreException) ex;
...
errorMessage = new ErrorMessageDTO(e, uri);
} else {
errorMessage = new ErrorMessageDTO(ex, uri);
...
}
return new ResponseEntity<ErrorMessageDTO>(errorMessage, a);
}
}
CountryService.java
这是我的Service类中的一个方法。
@EnableCaching
@EnableDiscoveryClient
@EnableAspectJAutoProxy
@SpringBootApplication(scanBasePackages = {
"com.something1.something2.something3.common.exception",
"com.something1.something2.something3.common.util.logged",
"com.something1.something2.something3.country"
})
public class CountryApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(CountryApplication.class, args);
}
...
}
CountryServiceTest.java
@GetMapping("/{id:\\d+}")
public CountryDTO getCountryById(@PathVariable("id") Integer id) throws CoreException {
Country countryEntity = this.countryRepository.findOne(id);
// requesting for id that does not exist
if (countryEntity == null) {
throw new CoreException(CoreError.ENTITY_NOT_FOUND);
}
return this.countryMapper.daoToDto(countryEntity);
}
正如我上面所描述的,问题是在测试方法的第二个请求中,@SpringBootTest
@AutoConfigureMockMvc
@AutoConfigureTestDatabase
@RunWith(SpringRunner.class)
public class CountryServiceTest {
...
@Autowired
private MockMvc mockMvc;
@Test
public void getByIdTest() throws Exception {
// Get by id exists
mockMvc.perform(get("/2"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andDo(print());
// Get by id not exists. NOT WORKING
mockMvc.perform(get("/100000"))
.andExpect(status().isNotFound())
.andExpect(content().contentType(contentType));
}
}
没有被调用,测试失败了抛出:
CoreExceptionHandler
。
公共模块的依赖性配置得很好(至少当我在非测试模式下部署时),因为我也将它用于其他事情,而且当我没有测试时会调用ExceptionHandler。
另一个奇怪的事情是,当我部署我的测试时,Spring Boot的日志显示NestedServletException: Request processing failed; nested exception is com.something1.something2.something3.common.exception.CoreException
被检测到。这就是这条线。 CoreExceptionHandler
答案 0 :(得分:0)
有两个问题如下所述:
(1)您的MockMvc
课程中没有为CountryServiceTest
对象设置ControllerAdvice,如下所示:
MockMvc mockMvc = standaloneSetup(yourController)
.setHandlerExceptionResolvers(new CoreExceptionHandler())
.build();
(2)由于CoreException
是Spring容器NestedServletException
的包装器,因此您需要使用exception.getCause()
检查您的异常,如下所示:< / p>
@ControllerAdvice
public class CoreExceptionHandler {
@ExceptionHandler(value = Exception.class)
public ResponseEntity<ErrorMessageDTO> handleException(Exception ex,
HttpServletRequest request) {
// Getting servlet request URL
String uri = request.getRequestURI();
HttpStatus a;
ErrorMessageDTO errorMessage;
//check with exception cause
if (ex.getCause() instanceof CoreException) {
CoreException e = (CoreException) ex;
...
errorMessage = new ErrorMessageDTO(e, uri);
} else if (ex instanceof CoreException) {
//this block will be used only when direct CoreException triggered
CoreException e = (CoreException) ex;
...
errorMessage = new ErrorMessageDTO(e, uri);
} else {
errorMessage = new ErrorMessageDTO(ex, uri);
...
}
return new ResponseEntity<ErrorMessageDTO>(errorMessage, a);
}
}
另外,我建议不要在一个通用方法中处理所有异常类型,这将非常难以支持/维护,而是使用多个CoreExceptionHandler
方法/类拆分@ExceptionHandler
强>