Получил неожиданный вывод в MRUnit

Я получаю следующую ошибку MRUnit:

ОШИБКА mrunit.TestDriver: получен неожиданный вывод (60, mrdp.MyCustomClass@73207f36)

ОШИБКА mrunit.TestDriver: отсутствует ожидаемый результат (60, mrdp.MyCustomClass@6f73cf45) в позиции 0

Я создал MyCustomClass который реализует Writableи имеет 4 атрибута int. Это выходное значение моего Mapper.

Ниже приведен код MRUnit-теста в Mapper:

@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 должен вызвать его сеттер setAttr1(1)при нахождении "1" в new Text("60,5596,1,256") здесь выше.

Как я могу проверить этот результат с помощью пользовательского класса (с несколькими атрибутами)? Выполнение задания прошло успешно, я просто не знаю, как заставить работать тест MRUnit.

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

1 ответ

Решение

Вы должны переопределить equals() а также hascode() для ваших пользовательских классов, если вы хотите проверить на равенство. Если нет, то нет способа проверить "семантическое равенство". По умолчанию Object методы будут использованы. Это то, с чем вы сталкиваетесь. Для дальнейшего обсуждения см. Почему мне нужно переопределить методы equals и hashCode в Java?

Ниже приведен простой тест JUnit с использованием пользовательского класса CustomClass, Я закомментировал equals а также hashcode, Если вы запустите тест, он потерпит неудачу с сообщением, аналогичным тому, что вы получаете. Если вы удалите комментарии и запустите его, он пройдет.

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 имеют возможность создать их для вас.

  • Затмение: щелкните правой кнопкой мыши на классе -> Source -> Generate equals и hashcode
  • NetBeans: щелкните правой кнопкой мыши на редакторе исходного кода -> Вставить код -> равно () хэш-код ()

В обоих случаях вам нужно выбрать свойства, которые вы хотите включить (проверить) в равенства и хэш-код. Это единственные две IDE, которые я использую:-)

Другие вопросы по тегам