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"));
    }

Повідомлення про помилку таке:

Метод assrtEquals (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
Рішення насправді не перехід від однієї версії до іншої. Натомість допоможіть компілятору та усуньте двозначність, як я запропонував.
Паскаль Thivent

1
У будь-якому випадку, чи не повинні це бути ствердженняEquals (70.0d, eccen.get ("альфа")); ?
mhaller

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

1
@Rosarch Для цього конкретного випадку, це не є проблемою в JUnit 3.8.1, це не є проблемою в JUnit 4.3, це є проблемою в JUnit 4.4, це є проблемою в JUnit 4.5 (але метод з 2 подвоєння застаріло), це не проблема в JUnit 4.6 (метод видалено). Отже, зробіть свій вибір, але вам слід виправити код.
Паскаль Thivent

1

Можна використовувати метод

assertEquals(double expected, double actual, double delta)

Який буде враховувати помилку округлення, що є орієнтиром до плаваючої точки (див., Наприклад, цю публікацію ). Можна писати

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

Це означає, що до тих пір, поки ці дві величини відрізняються менше ніж 0,0001, вони вважаються рівними. Це має дві переваги:

  • Порівняє значення з плаваючою комою, як вони належать
  • Не потрібно подавати, оскільки три аргументи аргументу застосовуються лише до парних, а не до загальних об'єктів

0

Найпростіше рішення цієї проблеми - це просто передати другий параметр у примітив:

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

Неоднозначність видалено.

Це справедливо для будь-якого з підкласів Числа, наприклад:

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

Також вирішив би двозначність.

Однак, тепер, і з поважних причин, аргумент assrtEquals (подвійний, подвійний) застарілий, тому я закликаю вас використовувати метод з дельтою, як уже запропонували інші.

З поважних причин я маю на увазі те, що, враховуючи внутрішнє представлення подвійних чисел, два, мабуть, однакові подвійні числа можуть відрізнятися невідповідним нескінченно малим дробом і не пройдуть тест, але це не означає, що у вашому коді щось не так.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.