Java JUnit: метод X неоднозначен для типа Y


98

У меня были некоторые тесты, работающие нормально. Затем я переместил его в другой пакет и теперь получаю ошибки. Вот код:

import static org.junit.Assert.*;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.jgrapht.Graphs;
import org.jgrapht.WeightedGraph;
import org.jgrapht.graph.DefaultWeightedEdge;
import org.jgrapht.graph.SimpleWeightedGraph;
import org.junit.*; 

@Test
    public void testEccentricity() {
        WeightedGraph<String, DefaultWeightedEdge> g = generateSimpleCaseGraph();
        Map<String, Double> eccen = JGraphtUtilities.eccentricities(g);

        assertEquals(70, eccen.get("alpha"));
        assertEquals(80, eccen.get("l"));
        assertEquals(130, eccen.get("l-0"));
        assertEquals(100, eccen.get("l-1"));
        assertEquals(90, eccen.get("r"));
        assertEquals(120, eccen.get("r-0"));
        assertEquals(130, eccen.get("r-1"));
    }

Сообщение об ошибке следующее:

Метод assertEquals (Object, Object) неоднозначен для типа JGraphtUtilitiesTest

Как я могу это исправить? Почему возникла эта проблема, когда я переместил класс в другой пакет?


расскажите нам, как объявлен ваш класс. Мне кажется, что вы унаследовали от JUnit3, а затем попытались статически импортировать из JUnit4.
bmargulies

да, на самом деле, у меня был JUnit3 в пакете A и JUnit4 в пакете B, где я изначально написал эти тесты. Затем я переключился с пакета B на пакет A, и возникла проблема. Но я не вижу в этом классе ничего, что указывало бы на JUnit 3. Где это объявлено?
Ник Хайнер

@Rosarch Эти JGraphtUtilities доступны где-нибудь? Я не вижу методов создания эксцентриситета в JGraphT!
Ник

Ответы:


205

Метод assertEquals (Object, Object) неоднозначен для типа ...

Эта ошибка означает, что вы передаете doubleи и Doubleв метод, который имеет две разные сигнатуры: assertEquals(Object, Object)и assertEquals(double, double)обе из них могут быть вызваны благодаря автобоксу.

Чтобы избежать двусмысленности, убедитесь, что вы вызываете assertEquals(Object, Object)(передавая два двойных значения) или assertEquals(double, double)(передавая два двойных значения).

Итак, в вашем случае вы должны использовать:

assertEquals(Double.valueOf(70), eccen.get("alpha"));

Или:

assertEquals(70.0d, eccen.get("alpha").doubleValue());

хорошо, или я мог бы просто переключить его на использование JUnit 4 вместо JUnit 3. Как мне это сделать?
Ник Хайнер

8
Решение не в том, чтобы переключаться с одной версии на другую. Вместо этого помогите компилятору и устраните двусмысленность, как я предлагал.
Паскаль Тивент

1
В любом случае, не должно быть assertEquals (70.0d, eccen.get ("alpha")); ?
mhaller

3
@mahller Не уверен, с кем вы разговариваете, но, даже если он более правильный, чем код OP, все равно неоднозначно, если в версии JUnit есть и то, assertEquals(Object, Object)и другое, assertEquals(double, double)как в случае JUnit 4.4, 4.5. Но, как я уже сказал, изменение версии JUnit - не настоящее решение, просто устраните проблему.
Паскаль Тивент

1
@Rosarch Для этого конкретного случая, это не является проблемой в JUnit 3.8.1, это не является проблемой в JUnit 4.3, это является проблемой в JUnit 4.4, это является проблемой в JUnit 4.5 (но метод с 2 doubles устарел), это не проблема в JUnit 4.6 (метод был удален). Итак, сделайте свой выбор, но вам следует исправить код.
Паскаль Тивент

1

Вы можете использовать метод

assertEquals(double expected, double actual, double delta)

Что будет учитывать ошибку округления, которая связана с плавающей запятой (см., Например, этот пост ). Ты можешь написать

assertEquals(70, eccen.get("alpha"), 0.0001);

Это означает, что до тех пор, пока два значения различаются менее чем на 0,0001, они считаются равными. У этого есть два преимущества:

  • Сравнивает значения с плавающей запятой, как и предполагалось
  • Нет необходимости приводить, поскольку три аргумента assert применяются только к двойникам, а не к универсальным объектам.

0

Самое простое решение этой проблемы - просто преобразовать второй параметр в примитив:

assertEquals(70, (double)eccen.get("alpha"));

Устранена двусмысленность.

Это справедливо для любого из подклассов Number, например:

assertEquals(70, (int)new Integer(70));

Решил бы тоже двусмысленность.

Однако assertEquals (double, double) на данный момент устарел и по уважительным причинам, поэтому я рекомендую вам использовать метод с дельтой, как уже предлагали другие.

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.