则么做网站,商丘猎狐网络,网站域名有效期,可以做很多个网站然后哭推广很抱歉没有写一段时间#xff0c;但是我正忙于为DZone编写JBoss Drools Refcard#xff0c;而且我正在写一本有关Mockito的书#xff0c;因此我没有太多时间来写博客了…… 无论如何#xff0c;最近在我当前的项目中#xff0c;我对使用Mockito和JAXB结构进行单元测试有一… 很抱歉没有写一段时间但是我正忙于为DZone编写JBoss Drools Refcard而且我正在写一本有关Mockito的书因此我没有太多时间来写博客了…… 无论如何最近在我当前的项目中我对使用Mockito和JAXB结构进行单元测试有一个有趣的情况。 我们已经从为我们提供的模式生成的嵌套了非常深的JAXB结构这意味着我们无论如何都无法更改它。 让我们看一下项目结构 项目结构非常简单–有一个Player.xsd模式文件该文件由于使用了jaxb2-maven-plugin生成了与目标/ jaxb /文件夹中定义的相应包中的模式相对应的生成的JAXB Java类。 pom.xml 。 说到其中让我们看一下pom.xml文件。 pom.xml project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersiongroupIdcom.blogspot.toomuchcoding/groupIdartifactIdmockito-deep_stubs/artifactIdversion0.0.1-SNAPSHOT/versionpropertiesproject.build.sourceEncodingUTF-8/project.build.sourceEncodingmaven.compiler.source1.6/maven.compiler.sourcemaven.compiler.target1.6/maven.compiler.target/propertiesrepositoriesrepositoryidspring-release/idurlhttp://maven.springframework.org/release/url/repositoryrepositoryidmaven-us-nuxeo/idurlhttps://maven-us.nuxeo.org/nexus/content/groups/public/url/repository/repositoriesdependenciesdependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion4.10/version/dependencydependencygroupIdorg.mockito/groupIdartifactIdmockito-all/artifactIdversion1.9.5/versionscopetest/scope/dependency/dependenciesbuildpluginManagementpluginsplugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-compiler-plugin/artifactIdversion2.5.1/version/plugin/plugins/pluginManagementpluginsplugingroupIdorg.codehaus.mojo/groupIdartifactIdjaxb2-maven-plugin/artifactIdversion1.5/versionexecutionsexecutionidxjc/idgoalsgoalxjc/goal/goals/execution/executionsconfigurationpackageNamecom.blogspot.toomuchcoding.model/packageNameschemaDirectory${project.basedir}/src/main/resources/xsd/schemaDirectory/configuration/plugin/plugins/build/project 除了先前定义的项目依赖关系外如先前在配置节点中的jaxb2-maven-plugin中所述您还可以基于schemaDirectory值定义packageName值该值定义将JAXB类生成到哪个程序包插件可以在其中找到适当的架构文件。 说到这让我们检查一下Player.xsd模式文件 类似于我的Spring JMS自动消息转换文章中提供的文件 ?xml version1.0 encodingUTF-8?
xsd:schema xmlns:xsdhttp://www.w3.org/2001/XMLSchemaxsd:element namePlayerDetailsxsd:complexTypexsd:sequencexsd:element nameName typexsd:string/xsd:element nameSurname typexsd:string/xsd:element namePosition typePositionType/xsd:element nameAge typexsd:int/xsd:element nameClubDetails typeClubDetails//xsd:sequence/xsd:complexType/xsd:elementxsd:complexType nameClubDetailsxsd:sequencexsd:element nameTeamName typexsd:string/xsd:element nameCountry typeCountryDetails//xsd:sequence/xsd:complexTypexsd:complexType nameCountryDetailsxsd:sequencexsd:element nameCountryName typexsd:string/xsd:element nameCountryCode typeCountryCodeDetails//xsd:sequence/xsd:complexTypexsd:complexType nameCountryCodeDetailsxsd:sequencexsd:element nameCountryName typexsd:string/xsd:element nameCountryCode typeCountryCodeType//xsd:sequence/xsd:complexTypexsd:simpleType nameCountryCodeTypexsd:restriction basexsd:stringxsd:enumeration valuePL/xsd:enumeration valueGER/xsd:enumeration valueFRA/xsd:enumeration valueENG/xsd:enumeration valueESP//xsd:restriction/xsd:simpleTypexsd:simpleType namePositionTypexsd:restriction basexsd:stringxsd:enumeration valueGK/xsd:enumeration valueDEF/xsd:enumeration valueMID/xsd:enumeration valueATT//xsd:restriction/xsd:simpleType/xsd:schema 如您所见我正在定义一些复杂的类型即使它们可能没有商业意义但您可以在现实生活中找到这样的例子。 让我们找出我们要测试的方法的外观。 在这里我们有PlayerServiceImpl实现了PlayerService接口 package com.blogspot.toomuchcoding.service;import com.blogspot.toomuchcoding.model.PlayerDetails;/*** User: mgrzejszczak* Date: 08.06.13* Time: 19:02*/
public class PlayerServiceImpl implements PlayerService {Overridepublic boolean isPlayerOfGivenCountry(PlayerDetails playerDetails, String country) {String countryValue playerDetails.getClubDetails().getCountry().getCountryCode().getCountryCode().value();return countryValue.equalsIgnoreCase(country);}
} 我们从JAXB生成的类中获取嵌套元素。 尽管它违反了Demeter的定律但调用结构的方法却很常见因为JAXB生成的类实际上是结构因此我完全同意Martin Fowler的观点即应将其称为Demeter的建议 。 无论如何让我们看看如何测试该方法 Testpublic void shouldReturnTrueIfCountryCodeIsTheSame() throws Exception {//givenPlayerDetails playerDetails new PlayerDetails();ClubDetails clubDetails new ClubDetails();CountryDetails countryDetails new CountryDetails();CountryCodeDetails countryCodeDetails new CountryCodeDetails();playerDetails.setClubDetails(clubDetails);clubDetails.setCountry(countryDetails);countryDetails.setCountryCode(countryCodeDetails);countryCodeDetails.setCountryCode(CountryCodeType.ENG);//whenboolean playerOfGivenCountry objectUnderTest.isPlayerOfGivenCountry(playerDetails, COUNTRY_CODE_ENG);//thenassertThat(playerOfGivenCountry, is(true));} 该函数检查是否具有相同的国家地区代码是否从该方法中获取了一个真正的布尔值。 唯一的问题是要创建输入消息时发生的集合和实例化的数量。 在我们的项目中嵌套元素的数量是原来的两倍因此您只能想象创建输入对象所需的代码数量… 那么如何改善此代码呢 Mockito与Mockito.mock…方法的RETURN_DEEP_STUBS默认答案一起出手 Testpublic void shouldReturnTrueIfCountryCodeIsTheSameUsingMockitoReturnDeepStubs() throws Exception {//givenPlayerDetails playerDetailsMock mock(PlayerDetails.class, RETURNS_DEEP_STUBS);CountryCodeType countryCodeType CountryCodeType.ENG;when(playerDetailsMock.getClubDetails().getCountry().getCountryCode().getCountryCode()).thenReturn(countryCodeType);//whenboolean playerOfGivenCountry objectUnderTest.isPlayerOfGivenCountry(playerDetailsMock, COUNTRY_CODE_ENG);//thenassertThat(playerOfGivenCountry, is(true));} 因此这里发生的是您使用Mockito.mock…方法并提供了RETURNS_DEEP_STUBS答案该答案将为您自动创建模拟 。 请注意不能嘲笑枚举这就是为什么您不能在Mockito.when…函数playerDetailsMock.getClubDetails。getCountry。getCountryCode。getCountryCode。getValue中编写代码的原因。 总结一下您可以比较两个测试的可读性并通过使用Mockito RETURNS_DEEP_STUBS默认答案来了解使用JAXB结构有多清晰。 当然该示例的资源可从BitBucket和GitHub获得 。 参考 Mockito – JAXB的RETURNS_DEEP_STUBS来自我们的JCG合作伙伴 Marcin Grzejszczak位于Blog上用于编码上瘾者博客。 翻译自: https://www.javacodegeeks.com/2013/07/mockito-returns_deep_stubs-for-jaxb.html