我已经完成了将模拟代码从EasyMock 1样式升级到EasyMock 2/3样式的任务(这是时候了,考虑到EasyMock 1的大部分已在2005年弃用,并在2010年删除,但我们仍然在2014年使用它!)。我已经找到了如何升级大多数东西的方法,但是在将实现ArgumentsMatcher的匹配器(在我们使用的EasyMock 1.0.1中称为ParameterMatcher)转换为实现。在EasyMock 1的IArgumentMatcher中,matches()的方法签名为:ArgumentsMatcher但是EasyMock 2/3的matches(Object[] expected, Object[] actual)中matchs()的方法签名是:IArgumentMatcher我从一个教程中发现,使用matches(Object argument),可以通过将期望的参数移到构造函数中来转换匹配器,如下所示:public class GenericMatcher implements IArgumentMatcher { private Object expected; public GenericMatcher(Object expected) { this.expected = expected; } public boolean matches(Object actual) { return this.expected.equals(actual); //Or some other comparison }}这很好用,但前提是传入的数组包含一个元素。我的代码中有许多匹配器,显然可以一次匹配多个元素。例如:public boolean matches(Object[] expected, Object[] actual) { if (expected[0].equals(actual[0]){ return expected[1].getName().equals(actual[1]).getName()); } else { return false; }}我不知道如何将其转换为IArgumentsMatcher。尽管我可以在构造函数中放置多个参数,但IArgumentMatcher接口仅声明match()方法具有一个参数,因此我无法进行多个比较。自然地,我继承的代码是没有文档的,不幸的是,EasyMock文档似乎缺少这两个版本中的matchs方法中实际传递的内容。那么我将如何转换此匹配器? 最佳答案 在相当多地查看现有代码并进行分段处理之后,我弄清楚了发生了什么。首先,我们将回到在EasyMock 1代码中调用此匹配器的位置:myMock.find("Testing", new DateSearchCriteria());myControl.setMatcher(new GenericMatcher());myControl.setReturnValue(AppConstants.TODAY);这里有两件事:首先,find方法有两个参数。其次,仅分配了一个匹配器。经过反复试验,我发现Match()的EasyMock 1 ArgumentMatcher版本采用数组,因为它正在比较调用中的所有参数。因此,在这种情况下,Object[] expected = ["Testing", new DateSearchCriteria()]。问题示例中的自定义匹配器检查第一个参数是否相等,第二个参数是否具有相同的名称,并隐含地理解第一个参数将为String,第二个参数将为DateSearchCriteria。这不是实现匹配器的好方法,因为如果进行任何重构,例如更改方法签名或更改DateSearchCriteria的实现,则匹配器将中断。但是由于EasyMock 1仅允许您为每种方法设置一个匹配器,因此这是匹配事物的唯一方法。EasyMock 2和3改进了功能,因此您可以为每个单独的参数设置匹配器,而不是为整个方法设置一次。这就是为什么IArgumentMatcher matches()现在只使用一个Object而不是Object数组的原因。因为它只检查一个论点,而不是一次检查所有论点。因此,上面的EasyMock 1代码在EasyMock 2/3中如下所示:expect(persistenceManager.find(eq("Testing"), eqName(new DateSearchCriteria()))) .setReturnValue(AppConstants.TODAY));eq()方法是EasyMock中内置的相等匹配器。 eqName()方法将是一个实现如下的自定义方法:public <T> T eqName(T in) { reportMatcher(new NameMatcher(in)); return null;}并且NameMatcher将通过执行与旧匹配器对参数#1所做的相同检查来实现:public class NameMatcher implements IArgumentMatcher { private Object expected; public NameMatcher(Object expected) { this.expected = expected; } @Override public void appendTo(StringBuffer buffer) { buffer.appendTo("Name is \"" + expected.getName() + "\""); } @Override public boolean matches(Object actual) { return expected.getName().equals(actual.getName()); }}因此,总而言之,像EasyMock 1一样的多参数match()方法正在对输入数组的每个元素进行比较,实际上是在检查要模拟的方法的每个参数。它正在对每个参数的状态进行假设,并且如果进行重构,则很容易破坏。 EasyMock 2使匹配器按参数而不是按方法。因此,将EasyMock 1 ArgumentsMatcher转换为EasyMock 2/3 IArgumentMatcher所需要做的是将每个参数匹配项基本上拆分为自己的匹配器。在上面的示例中,旧的匹配器测试了参数0的相等性和参数1的相等性。因此,当您声明方法嘲笑时,您在参数0上放置了一个相等匹配器(内置在EasyMock 2/3中)并为参数1创建自己的名称匹配器。它们不共享匹配器,它们是独立的独立匹配器。关于java - 将多参数Match()从EasyMock 1 ArgumentsMatcher转换为EasyMock 2/3 IArgumentMatcher,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21149572/
10-10 10:33