我有一个spring控制器,它有多个spring bean依赖项(自动连接的服务)。每个服务也有很少的spring bean依赖项(自动连接的daos)。例如,控制器登录方式:
@Controller
@RequestMapping("/")
public class ClientAccessController extends BaseController {
@Autowired
IFileService fileService;
@Autowired
MidTierService midTierService;
/**
* Used to handle client login requests
* Works as a proxy to MID tier server
*
* @param request LoginRequest(userLogin, userPassword, compId, installGuid)
* @return LoginResponse (token)
* @throws Exception
*/
@RequestMapping(method = RequestMethod.POST, value = "/login", headers = "Content- type=application/json")
public ResponseEntity<LoginResponse> login(@RequestBody LoginRequest request) throws Exception {
log.info("LOGIN REQUEST [ " + request.toString() + " ]");
String token = midTierService.authenticateNativeClient(request.getLogin(), request.getPassword(), request.getGuId(),
request.getCompid().toString());
LoginResponse response = new LoginResponse(token);
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
ResponseEntity<LoginResponse> responseEntity = new ResponseEntity<>(response, HttpStatus.OK);
log.info("LOGIN RESPONSE [ " + response.toString());
return responseEntity;
}
我正在尝试只为控制器ClienAccessController
编写JUnit测试。但是当我在测试类中自动连接ClientAccessController
时,spring会尝试为所有控制器依赖项和所有嵌套依赖项(daos等)创建beans,但我真的不需要它们,只需要MidTierService
。那么,我应该怎么做才能排除嵌套的bean初始化,并且只在测试类中使用我需要的东西呢?
发布于 2012-10-30 13:09:22
Spring允许不止一种方式访问@Autowired
成员。对我来说,更好的方法(从可测试性的角度来看)是对构造函数进行@Autowired
。因此,我将为ClientAccessController
创建一个如下所示的构造函数:
@Autowired
public ClientAccessController(final IFileService fileService, final MidTierService midTierService) {
this.fileService = fileService;
this.midTierService = midTierService;
}
如果您的自动装配有点复杂(因为它使用@Qualifier
或@Value
),那么可以使用参数注释完成更多工作。
@Autowired
public ClientAccessController(@Qualifier("myFileService") final IFileService fileService,
@Qualifier("myMidTierService") final MidTierService midTierService) {
this.fileService = fileService;
this.midTierService = midTierService;
}
这样,您就可以很容易地使用模拟对象或存根来设置此类以进行测试。
@Test
public void testClientAccessController() {
final IFileService mockFileService = Mockito.mock(IFileService.class);
final MidTierService mockMidTierService = Mockito.mock(MidTierService.class);
final ClientAccessController controller = new ClientAccessController(mockFileService, mockMidTierService);
//test it
}
发布于 2013-04-08 17:01:29
我没有使用所有依赖项作为参数来创建构造函数,而是为每个依赖项创建了一个set方法。这样,我就可以在测试中模拟这些依赖项,并用setter注入它们。因此,测试的结果如下:
@Test
public void testClientAccessController() {
final IFileService mockFileService = Mockito.mock(IFileService.class);
final MidTierService mockMidTierService = Mockito.mock(MidTierService.class);
final ClientAccessController controller = new ClientAccessController();
controller.setFileService(mockFileService);
controller.setMidTierService(mockMidTierService);
//test it
}
我还建议您将这些设置器创建为protected
,并将测试用例放在与您正在测试的类相同的包中。
https://stackoverflow.com/questions/13139662
复制相似问题