Предотвратить раскорчевка метод Equals


Я хотел бы протестировать свой метод Class ' equals (), но Mockito, кажется, вызывает версию заглушки каждый раз. Мой тест заключается в следующем;

PluginResourceAdapter adapter = mock (PluginResourceAdapter.class);
PluginResourceAdapter other = mock (PluginResourceAdapter.class);

when(adapter.getNumberOfEndpointActivation()).thenReturn(1);
when(other.getNumberOfEndpointActivation()).thenReturn(0);

boolean result = adapter.equals(other);
assertFalse(result);

Я знаю, что не могу заглушить метод equals, что означает, что Mockito должен вызывать мою реальную реализацию, но это не так.

Я также попробовал это:

when (adapter.equals(any()).thenCallRealMethod()

Но я получаю тот же результат.

3 10

3 ответа:

Даже за пределами ограничений Mockito, Это не имеет большого смысла для издевательского объекта использовать реальный метод equals, если только по этой причине методы equals почти всегда используют поля, и издевательские объекты никогда не запускают ни один из своих конструкторов или инициализаторов полей.

Кроме того, имейте в виду, что вы тестируете: в тесте Foo, в идеале, вы никогда не должны издеваться над Foo, даже чтобы настроить Foo Для сравнения. В противном случае легко непреднамеренно проверить, что Mockito работает, вместо того, чтобы проверять логику вашего собственного компонента.

У вас есть несколько обходных путей:

  • Как уже упоминал Гаррет Холл, создавайте реальные объекты. Это может потребовать факторинга "объектов данных" из служб, которые их используют, и издевательства над службами при использовании реальных объектов данных. Это, вероятно, хорошая идея в целом.

  • Создайте ручной макет или подделку, подклассировав PluginResourceAdapter или реализовав соответствующий интерфейс за пределами Mockito. Этот позволяет определить все необходимые методы, включая equals и hashCode.

  • Создайте метод equivalentTo, который отличается от метода equals (и, следовательно, не так полезен для объектов Map или Set, например), но имеет поддельную семантику, которую вы можете определить самостоятельно.

    Это также позволит вам свободно тестировать equivalentTo с макетом и просто делегировать equals этой предположительно хорошо протестированной реализации.

  • Извлеките объект, который проверяет равенство, и издевайтесь над ним. Вы также можете использовать гуаву.Equivalence там, или в Comparator , где вы тестируете a.compareTo(b) == 0.
    class YourClass {
      class AdapterEquivalence {
        boolean adaptersAreEqual(
            PluginResourceAdapter a, PluginResourceAdapter b) {
          return a.equals(b);
        }
      }
    
      /** Visible for testing. Replace in tests. */
      AdapterEquivalence adapterEquivalence = new AdapterEquivalence();
    }
    

Обратите внимание, что еще один потенциальный обходной путь - шпионаж за существующими экземплярами - также переопределит equals и hashCode и здесь я тебе не помогу.

Если вы хотите проверить реальное equals затем нужно создать реальный объект и вызвать для него метод equals. Я не знаю, почему вы используете насмешки.

По умолчанию equals () возвращает true, если объект имеет тот же адрес в памяти.
Так что

PluginResourceAdapter adapter; PluginResourceAdapter other; adapter = other = mock (PluginResourceAdapter.class);

возвращает вам истину. Если вы хотите ложного использования

PluginResourceAdapter adapter = mock (PluginResourceAdapter.class); PluginResourceAdapter other = mock (PluginResourceAdapter.class);