-
- 为什么用Groovy写单元测试
它与Java 平台无缝的集成,它是基于 Java 的语言(不像其他语言,是对 JRE 的替代,因此可能基于旧版的处理器),对于 Java 开发人员来说,Groovy 意味着一条短得让人难以置信的学习曲线。而且一旦将这条学习曲线拉直,Groovy 就能提供一个无与伦比的快速开发平台。
从这个角度来说,Groovy 成功的秘密,在于它的语法 就是 Java 语法,但是规则更少。例如,Groovy 不要求使用分号,变量类型和访问修饰符也是可选的。而且,Groovy 利用了标准的 Java 库,这些都是您已经很熟悉的,包括
Collections和File/IO。而且,您还可以利用任何 Groovy 提供的 Java 库,包括 JUnit。事实上,令人放松的类 Java 语法、对标准 Java 库的重用以及快捷的生成-运行周期,这些都使 Groovy 成为快速开发单元测试的理想替代品。
-
如何使用Groovy进行Mock测试
用Groovy进行Mock要比JMockit之类的简单很多,下面举例还演示如何使用待测试类 折叠源码123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657@Slf4jpublicclassObjectDataControllerimplementsIObjectDataController {@ResourceObjectDescribeServiceImpl objectDescribeService;@ResourceObjectDataProxy objectDataProxy;@ResourceLayoutServiceImpl layoutService;@OverridepublicFcpServiceResult findById(FindObjectDataArg arg) {if(validateArg(arg)) {returnFCPUtils.buildFcpServiceResult(null, Status.CODE_ERROR, Status.MESSAGE_PARAMETER_IS_NULL,null);}try{IObjectDescribe describe;describe = getObjectDescribeInstance(arg, arg.getObject_describe_id(), arg.getObject_describe_apiname(), Id.parse(arg.getObject_describe_id()));if(null== describe) {returnFCPUtils.buildFcpServiceResult(null, Status.CODE_NOT_FOUND, Status.MESSAGE_NOT_FOUND,null);}IObjectData objectData = objectDataProxy.findById(Id.parse(arg.getObject_data_id()), describe.getTenantId(), describe.getApiName());returngetFcpServiceResult(arg, describe, objectData);}catch(Exception e) {log.error("find object data err. tenant_id:{},object_describe_id:{}, object_data_id:{}", arg.getEnterpriseId(), arg.getObject_describe_id(), arg.getObject_data_id(), e);returnFCPUtils.buildFcpServiceResult(null, Status.CODE_ERROR, Status.MESSAGE_ERROR, e);}}privateFcpServiceResult getFcpServiceResult(FindObjectDataArg arg, IObjectDescribe describe, IObjectData objectData) {if(null== objectData) {returnFCPUtils.buildFcpServiceResult(null, Status.CODE_NOT_FOUND, Status.MESSAGE_NOT_FOUND,null);}else{ILayout layout =null;if(arg.isInclude_layout()) {layout = layoutService.findDefault(describe.getApiName(), arg.getEnterpriseId());if(null== layout) {returnFCPUtils.buildFcpServiceResult(null, Status.CODE_NOT_FOUND, Status.MESSAGE_NOT_FOUND,null);}}returnFCPUtils.buildFcpServiceResult(FCPResult.builder().objectDescribe(((ObjectDescribe) describe).getContainerDocument()).objectData(objectData).layout(layout !=null? ((Layout) layout).getContainerDocument() :null).build(), Status.CODE_OK, Status.MESSAGE_OK,null);}}privateIObjectDescribe getObjectDescribeInstance(FindObjectDataArg arg, String object_describe_id, String object_describe_apiname, Id parse) {IObjectDescribe describe;if(Strings.isNullOrEmpty(object_describe_id)) {describe =objectDescribeService.findByTenantIdAndObjectDescribeApiName(arg.getEnterpriseId(), object_describe_apiname);}else{describe = objectDescribeService.findById(arg.getEnterpriseId(), parse);}returndescribe;}}
我们需要测试ObjectDataController中的findById方法, 在findById方法中用到了ObjectDescribeService, objectDataProxy和 layoutService, 我们需要把这三个实例的对应方法mock掉来测试各种返回结果下的代码处理逻辑。在mock这些class之前,首先需要保证ObjectDataController中有对应的三个实例的setter方法,如下代码所示
对应的setter方法 折叠源码1234567891011121314@OverridepublicvoidsetObjectDataService(ObjectDataProxy proxy) {this.objectDataProxy = proxy;}@OverridepublicvoidsetObjectDescribeService(ObjectDescribeServiceImpl objectDescribeService) {this.objectDescribeService = objectDescribeService;}@OverridepublicvoidsetLayoutService(LayoutServiceImpl layoutService) {this.layoutService = layoutService;}实现了对应的setter方法后,我们就可以写unitTest了,最后的代码如下所示
单元测试类 折叠源码1234567891011121314151617181920212223242526272829303132333435@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(value ="classpath:applicationContext.xml")classObjectDataFCPTest {@AutowiredIObjectDataController objectDataController@Testpublicvoidtest_find_by_id_success()throwsException {def data = [getEnterpriseId : { -> test_tenant_1 },getUserId : { -> user_id },getObject_data_id : { -> id },getObject_describe_id :{ -> id}] as FindObjectDataArgdef mock = [findById: {Id id, String eid, String api -> after}] as ObjectDataProxyobjectDataController.setObjectDataService(mock)def mockDescribe = [findById: { String tenantId, Id id -> describe },findByTenantIdAndObjectDescribeApiName : {String tenantId, String apiName -> describe}] as ObjectDescribeServiceImplobjectDataController.setObjectDescribeService(mockDescribe)FcpServiceResult result = objectDataController.findById(data);FCPResult fcpResult = (FCPResult)result.getResult();ObjectData config = (ObjectData) fcpResult.objectDataassertEquals(test_tenant_1, config.getTenantId())assertEquals(id, config.getId().strValue())assertEquals("example", config.getPackage())assertEquals("客户数据", config.getName())assertEquals(false, config.isDeleted())assertEquals(1, config.getVersion())assertEquals(user_id, config.getCreatedBy())assertEquals(user_id, config.getLastModifiedBy())}}最后的代码因为传入参数没有包含layout部分, 所以没有mock layoutService的对应方法, 整个mock过程就是这么简单。如果你想更深入的了解groovy的单元测试实现,可以了解下spock框架
- 为什么用Groovy写单元测试
来源:oschina
链接:https://my.oschina.net/u/4393962/blog/4138016