2014-10-18 2 views
4

Я столкнулся с https://code.google.com/p/hamcrest/issues/detail?id=130, чтобы добавить синтаксис сахара для совпадений Hamcrest. Но идея была отвергнута разработчиками Hamcrest.Как использовать (примитивный) автобоксинг/расширение с помощью Hamcrest?

Любые другие умные идеи, чтобы сделать тесты более читабельными, избегая необходимости вводить L за длинными?

@Test 
public void test1() { 
    int actual = 1; 
    assertThat(actual, is(1)); 
} 

@Test 
public void test2() { 
    long actual = 1L; 
    assertThat(actual, is(1)); // fails as expected is <1> but result was <1L> 
    // assertThat(actual, is(1L)); off course works.. 
} 

@Test 
public void test3() { 
    Long actual = new Long(1); 
    assertThat(actual, is(1)); // fails as expected is <1> but result was <1L> 
} 

ОБНОВЛЕНИЕ

Смотрите также ниже различий при сравнении, например, int и long с использованием Java laguage по умолчанию (==), стандартного junit assert (assertTrue) и метода hamcrest is(). Кажется, странный hamcrest doest не поддерживает сопоставление/сравнение long vs int, а остальное.

@Test 
public void test2() { 
    long actual = 1L; 
    int expected = 1; 
    assertTrue(expected == actual); // std java succeeds 
    assertEquals(expected, actual); // std junit succeeds 
    assertThat(actual, is(expected)); // hamcrest fails: Expected: is <1> but: was <1L> 
} 
+0

Simple is() - без явного добавления L - не будет работать, как описано в примере –

ответ

3

Это абсолютно не связано с проблемой, которую вы связываете, которая касается адресации неисправных статических анализаторов и была правильно отвергнута. Проблема, с которой вы столкнулись, распространена в Java при смешивании примитивных типов.

Чтобы избежать ввода этого L, вам необходимо предоставить перегруженные версии всех сокетов - не только is. Рассмотрим следующие примеры:

assertThat(longValue, greaterThan(1)); 
assertThat(longList, contains(1, 2, 3)); 

Update

Вы можете легко добавить свои собственные перегруженные версии для выполнения преобразования:

public static Matcher<Long> is(Integer value) { 
    return org.hamcrest.core.Is.is(value.longValue()); 
} 

Конечно, теперь, когда у вас есть один для преобразования из int до long Вы хотите использовать их для float и double:

public static Matcher<Long> is(Float value) { 
    return org.hamcrest.core.Is.is(value.longValue()); 
} 

public static Matcher<Long> is(Double value) { 
    return org.hamcrest.core.Is.is(value.longValue()); 
} 

Поскольку Java не будет автоматически конвертировать из byte в Integer *, вы также нуждается в версии для byte и short. Это довольно уродливо, но как насчет отливки других типов, например от int до double?

public static Matcher<Double> is(Integer value) { 
    return org.hamcrest.core.Is.is(value.doubleValue()); 
} 

Compile Error: Duplicate method is(Integer)

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

Учитывая гигантский беспорядок, который это создаст, я сомневаюсь, что авторы Hamcrest будут открыты для такого дополнения, учитывая низкий выигрыш. Честно говоря, вам гораздо лучше быть явным, используя 1L и 1.0 по мере необходимости.

* Хотя компилятор будет конвертировать из byte в int, которые могли бы быть в штучной упаковке для Integer.

+0

Возможно, я не понял проблему, с которой я связан. Я вижу, что он предлагает добавить (int | long | .. value) как методы. –

+0

В любом случае, см. Мое обновление в вопросе сравнения поведения int vs longs и Java/Junit. Это странный Hamcrest думает иначе (/ не поддерживает его). –

+0

Операторы сравнения Java выполняют преобразование как часть языка (тип coersion), а JUnit предоставляет несколько перегруженных форм для удобства. Hamcrest должен был бы предоставить намного более перегруженные формы, потому что у него есть еще много помощников. –

Смежные вопросы