在MRUnit中收到了意外的输出

3
我遇到了下面的MRUnit错误:
ERROR mrunit.TestDriver: 收到了意外的输出(60, mrdp.MyCustomClass@73207f36) ERROR mrunit.TestDriver:在位置0处缺少预期输出(60, mrdp.MyCustomClass@6f73cf45)
我创建了一个实现Writable接口、包含4个整数属性的MyCustomClass类。这是我的Mapper的输出值。
以下是Mapper的MRUnit测试代码:
@Test
public void testMapper() throws IOException {
    MyCustomClass result = new MyCustomClass();
    result.setAttr1(1);
    result.setAttr2(0);
    result.setAttr3(0);
    result.setAttr4(0);

    mapDriver.withInput(new LongWritable(1), new Text("60,5596,1,256"));
    mapDriver.addOutput(new Text("60"), result);
    mapDriver.runTest();
}

当Mapper在上述的new Text("60,5596,1,256")中定位到"1"时,它应该调用它的setter方法setAttr1(1)

我如何使用自定义类(带有多个属性)测试这个结果?作业执行成功,但我不知道如何使MRUnit测试正常工作。

$ hadoop fs -cat patterns/minmaxcount/outuserprefs/part*
23  mrdp.MyCustomClass@4cf15f6c
60  mrdp.MyCustomClass@4cf15f6c
1个回答

2
如果您想测试相等性,需要为自定义类覆盖equals()hashCode()方法。如果没有这样做,就无法测试“语义相等性”。将使用默认的Object方法,这就是您所面临的问题。有关进一步讨论,请参见为什么需要在Java中覆盖equals和hashCode方法? 以下是使用自定义类CustomClass的简单JUnit测试。我注释掉了equalshashcode。如果运行测试,它将失败,并显示类似于您收到的消息。如果删除注释并运行它,则会通过。
import static org.junit.Assert.*;
import org.junit.Test;

public class CustomClass {

    String firstName;
    String lastName;

    public void setFirstName(String firstName) { this.firstName = firstName; }
    public void setLastName(String lastName) { this.lastName = lastName; }

    @Test
    public void testEqaulity() {
        CustomClass clazz1 = new CustomClass();
        clazz1.setFirstName("Stack");
        clazz1.setLastName("Overflow");

        CustomClass clazz2 = new CustomClass();
        clazz2.setFirstName("Stack");
        clazz2.setLastName("Overflow");

        assertEquals(clazz1, clazz2);
    }

    /*
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result
                + ((firstName == null) ? 0 : firstName.hashCode());
        result = prime * result
                + ((lastName == null) ? 0 : lastName.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        CustomClass other = (CustomClass) obj;
        if (firstName == null) {
            if (other.firstName != null)
                return false;
        } else if (!firstName.equals(other.firstName))
            return false;
        if (lastName == null) {
            if (other.lastName != null)
                return false;
        } else if (!lastName.equals(other.lastName))
            return false;
        return true;
    }
    */
}

如果您没有实现这些方法的经验或知识,大多数IDE都有创建这些方法的选项。
  • Eclipse:右键单击类 -> Source -> Generate equals and hashcode
  • Netbeans:右键单击源编辑器 -> Insert Code -> equals() hashcode()
在两种情况下,您需要选择要包括(检查)在equals和hashcode中的属性。这是我使用的唯一两个IDE :-)

1
非常感谢,您的回答确实帮助我找到了 MRUnit 测试中的 "assertThat()"。在 http://java.dzone.com/articles/testing-mapreduce-mrunit 中找到了一些示例。 - guzu92

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接