gpt4 book ai didi

java - 将多参数 matches() 从 EasyMock 1 ArgumentsMatcher 转换为 EasyMock 2/3 IArgumentMatcher

转载 作者:行者123 更新时间:2023-12-02 06:19:20 27 4
gpt4 key购买 nike

我被分配了将我们的模拟代码从 EasyMock 1-style 升级到 EasyMock 2/3-style 的任务(现在是时候了,因为 EasyMock 1 的大部分内容已于 2005 年被弃用并于 2010 年被删除,但是我们2014 年仍在使用它!)。

我已经弄清楚如何升级大多数东西,但是在转换实现 ArgumentsMatcher 的匹配器(在 EasyMock 1.0 中称为 ParameterMatcher)时遇到了很多麻烦.1,我们正在使用)到实现 IArgumentMatcher 的类。

在 EasyMock 1 的 ArgumentsMatcher 中,matches() 的方法签名是:

匹配(预期对象[],实际对象[])

但是 EasyMock 2/3 的 IArgumentMatcher 中 matches() 的方法签名是:

匹配(对象参数)

我从教程中发现,使用 IArgumentsMatcher,您可以通过将预期参数移动到构造函数中来转换匹配器,如下所示:

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;
}
}

我不知道如何将其转换为IArgumentMatcher。虽然我可以在构造函数中放入多个参数,但 IArgumentMatcher 接口(interface)仅声明 match() 方法具有一个参数,因此我无法进行多重比较。

当然,我继承的代码没有文档记录,不幸的是 EasyMock 文档似乎有点缺乏任何版本中实际传递到 matches 方法中的内容。那么我该如何转换这个匹配器呢?

最佳答案

经过大量查看现有代码并进行分段操作后,我弄清楚了发生了什么。

首先,我们将回顾 EasyMock 1 代码中调用此匹配器的位置:

myMock.find("Testing", new DateSearchCriteria());
myControl.setMatcher(new GenericMatcher());
myControl.setReturnValue(AppConstants.TODAY);

这里有两件事:首先,find 方法有两个参数。其次,只分配了一个匹配器。经过一番尝试和错误,我发现 EasyMock 1 ArgumentMatcher 版本的 matches() 采用一个数组,因为它比较调用中的所有参数。因此,在本例中,Object[] Expected = ["Testing", new DateSearchCriteria()]。问题示例中的自定义匹配器检查第一个参数是否相等且第二个参数是否具有相同的名称,并隐含地理解第一个参数将是字符串,第二个参数将是 DateSearchCriteria。

这不是实现匹配器的好方法,因为如果您进行任何重构,例如更改方法签名或更改 DateSearchCriteria 的实现,匹配器就会中断。但由于 EasyMock 1 只允许您为每个方法设置一个匹配器,因此这是匹配事物的唯一方法。

EasyMock 2 和 3 改进了功能,以便您可以为每个单独的参数设置匹配器,而不是为整个方法设置一次。这就是为什么 IArgumentMatcher matches() 现在只接受一个对象,而不是一个对象数组;因为它只检查一个论点,而不是同时检查所有论点。因此上面的 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 中那样的多参数 matches() 方法,它对输入数组的每个元素进行比较,实际上是在检查正在模拟的方法的每个参数。它对每个参数的状态做出假设,如果重构,它很容易被破坏。 EasyMock 2 相反,为每个参数而不是每个方法创建匹配器。因此,要将 EasyMock 1 ArgumentsMatcher 转换为 EasyMock 2/3 IArgumentMatcher ,您需要做的就是基本上将每个参数匹配拆分为自己的匹配器。在上面的示例中,旧匹配器测试参数 0 上的相等性和参数 1 上的相等名称。因此,当您声明方法模拟时,您在参数 0 上放置一个相等匹配器(内置于 EasyMock 2/3 中)并为参数 1 创建您自己的名称匹配器。它们不共享匹配器,它们是单独的、独立的匹配器。

关于java - 将多参数 matches() 从 EasyMock 1 ArgumentsMatcher 转换为 EasyMock 2/3 IArgumentMatcher,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21149572/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com