java - 单元测试 - 检查方法调用是否具有不覆盖 equals 的对象

标签 java unit-testing testing mocking easymock

这是一个关于如何使用模拟对象对 Java 类进行单元测试的一般性问题。
我可以用这个例子总结我的问题。
假设我有一个名为 MyInterface.java 的接口(interface)和一个不覆盖 equals() 的“TwoString”对象

"双字符串.java"

   private String string1;
   private String string2;

   public TwoString(String string1, String string2) {
     this.string1 = string1;
     this.string2 = string2;
   }
   ...getters..setters..

“MyInterface.java”

void callMe(TwoString twoString);

然后我有 "MyClass.java" 对象。它的构造函数接受 MyInterface 的具体实现。
MyClass methodToTest() 包含以某种方式创建 TwoString 对象的逻辑。假设它将创建为

new TwoString("a","b")

因此,当调用 methodToTest() 时,它会创建此 TwoString 对象,该对象将传递给接口(interface)方法 callMe(TwoString twoString)

我基本上想模拟界面。使用此模拟创建一个 MyClass 对象。然后验证是否使用特定的 TwoString 实例调用了 mock 方法。

我正在使用 EasyMock,这是一些 java 代码

“MyClassTest.java”

public void test() throws Exception {   
   MyInterface myInterfaceMock = createMock(MyInterface.class);
   MyClass myClass = new MyClass(myInterfaceMock);

   myInterfaceMock.callMe(new TwoString("a","b"));   <--- fails here
   expectLastCall();
   replay(myInterfaceMock);

   myClass.methodToTest();
   verify(myInterfaceMock);

问题来了。我在调用中期望的 TwoString 对象

myInterfaceMock.callMe(new TwoString("a","b"));

与 MyClass.methodToTest() 中生成的不同,因为 TwoString.java 不会覆盖 equals。

我可以使用

跳过 TwoString 实例上的问题
myInterfaceMock.callMe((TwoString)anyObject());

但我想确保使用包含“a”作为 string1 和“b”作为 string2 的特定 TwoString 实例调用接口(interface)方法。

在这种情况下,TwoString 对象非常简单,很容易覆盖 equals 方法 - 但如果我需要检查更复杂的对象怎么办。

谢谢

编辑:

我会尝试通过这个示例使其更具可读性

public class MyClassTest {
    private MyClass myClass;
    private TaskExecutor taskExecutorMock;

    @Before
    public void setUp() throws Exception {
        taskExecutorMock = createMock(TaskExecutor.class);
        myClass = new MyClass(taskExecutorMock);
    }

    @Test
    public void testRun() throws Exception {
        List<MyObj> myObjList = new ArrayList<MyObj>();
        myObjList.add(new MyObj("abc", referenceToSomethingElse));

        taskExecutorMock.execute(new SomeTask(referenceToSomethingElse,  ???new SomeObj("abc", referenceToSomethingElse, "whatever")));   <--- ??? = object created using data in myObjList
        expectLastCall();
        replay(taskExecutorMock);

        myClass.run(myObjList);

        verify(taskExecutorMock);
    }
}

???SomeObj = myClass.run() 使用 myObjList 中包含的数据创建的对象。
假设 SomeObj 来自第三方库,它不会覆盖 equals。

我想确保 taskExecutorMock.execute() 方法是通过该 SomeObj 的特定实例调用的

我如何测试 myClass.run() 实际上是在使用正确的实例调用 taskExecutorMock 方法

最佳答案

可以使用 org.easymock.IArgumentMatcher 来使用自定义相等匹配方法。

它应该看起来像:

private static <T extends TwoString> T eqTwoString(final TwoString twoString) {
    reportMatcher(new IArgumentMatcher() {
        /** Required to get nice output */
        public void appendTo(StringBuffer buffer) {
            buffer.append("eqTwoString(" + twoString.getString1() + "," + twoString.getString2() + ")");
        }

        /** Implement equals basically */
        public boolean matches(Object object) {
            if (object instanceof TwoString) {
                TwoString other = (TwoString) object;
                // Consider adding null checks below
                return twoString.getString1().equals(object.getString1()) && twoString.getString2().equals(object.getString2());
            }
            else {
                return false;
            }
        }
    });
    return null;
}

并且使用如下:

myInterfaceMock.callMe(eqTwoString(new TwoString("a","b")));

有些细节可能不正确,但本质上我以前就是这样做的。还有另一个示例和更详尽的解释可用 in the EasyMock documentation .只需搜索 IArgumentMatcher

关于java - 单元测试 - 检查方法调用是否具有不覆盖 equals 的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1643073/

相关文章:

java - 错误 XPATH KML JDOM

java - 为什么抽象实现由 Map.values() 返回?

javascript - 针对不同浏览器的 JavaScript 中的一般单元测试概念/实践?

c - 嵌入式C测试开发管理

javascript - 如何对 Ext JS 应用程序进行端到端测试

Java 响应内容返回而不是 < 或 > < >

java - 使用 StringBuffer 时 FlatXmlDataSetBuilder 抛出 "java.net.MalformedURLException"

unit-testing - 如何让 NUnit 测试列表中的所有值,而不仅仅是第一个失败

c# - 如何在 C# 中对 PowerShell Core 二进制 cmdlet 进行单元测试

c# - 为什么我的 Entity Framework 测试失败了?