-
- 为什么用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@Slf4j
public
class
ObjectDataController
implements
IObjectDataController {
@Resource
ObjectDescribeServiceImpl objectDescribeService;
@Resource
ObjectDataProxy objectDataProxy;
@Resource
LayoutServiceImpl layoutService;
@Override
public
FcpServiceResult findById(FindObjectDataArg arg) {
if
(validateArg(arg)) {
return
FCPUtils.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) {
return
FCPUtils.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());
return
getFcpServiceResult(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);
return
FCPUtils.buildFcpServiceResult(
null
, Status.CODE_ERROR, Status.MESSAGE_ERROR, e);
}
}
private
FcpServiceResult getFcpServiceResult(FindObjectDataArg arg, IObjectDescribe describe, IObjectData objectData) {
if
(
null
== objectData) {
return
FCPUtils.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) {
return
FCPUtils.buildFcpServiceResult(
null
, Status.CODE_NOT_FOUND, Status.MESSAGE_NOT_FOUND,
null
);
}
}
return
FCPUtils.buildFcpServiceResult(FCPResult.builder().objectDescribe(((ObjectDescribe) describe).getContainerDocument()).objectData(objectData).layout(layout !=
null
? ((Layout) layout).getContainerDocument() :
null
).build(), Status.CODE_OK, Status.MESSAGE_OK,
null
);
}
}
private
IObjectDescribe 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);
}
return
describe;
}
}
我们需要测试ObjectDataController中的findById方法, 在findById方法中用到了ObjectDescribeService, objectDataProxy和 layoutService, 我们需要把这三个实例的对应方法mock掉来测试各种返回结果下的代码处理逻辑。在mock这些class之前,首先需要保证ObjectDataController中有对应的三个实例的setter方法,如下代码所示
对应的setter方法 折叠源码1234567891011121314@Override
public
void
setObjectDataService(ObjectDataProxy proxy) {
this
.objectDataProxy = proxy;
}
@Override
public
void
setObjectDescribeService(ObjectDescribeServiceImpl objectDescribeService) {
this
.objectDescribeService = objectDescribeService;
}
@Override
public
void
setLayoutService(LayoutServiceImpl layoutService) {
this
.layoutService = layoutService;
}
实现了对应的setter方法后,我们就可以写unitTest了,最后的代码如下所示
单元测试类 折叠源码1234567891011121314151617181920212223242526272829303132333435@RunWith
(SpringJUnit4ClassRunner.
class
)
@ContextConfiguration
(value =
"classpath:applicationContext.xml"
)
class
ObjectDataFCPTest {
@Autowired
IObjectDataController objectDataController
@Test
public
void
test_find_by_id_success()
throws
Exception {
def data = [
getEnterpriseId : { -> test_tenant_1 },
getUserId : { -> user_id },
getObject_data_id : { -> id },
getObject_describe_id :{ -> id}
] as FindObjectDataArg
def mock = [findById: {Id id, String eid, String api -> after}] as ObjectDataProxy
objectDataController.setObjectDataService(mock)
def mockDescribe = [findById: { String tenantId, Id id -> describe },
findByTenantIdAndObjectDescribeApiName : {String tenantId, String apiName -> describe}] as ObjectDescribeServiceImpl
objectDataController.setObjectDescribeService(mockDescribe)
FcpServiceResult result = objectDataController.findById(data);
FCPResult fcpResult = (FCPResult)result.getResult();
ObjectData config = (ObjectData) fcpResult.objectData
assertEquals(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