Использование ожиданий jmockit с сопоставителями и примитивными типами

Я использую jmockit для модульного тестирования (с TestNG), и у меня возникают проблемы с использованием класса Expectations для имитации метода, который принимает примитивный тип (логическое значение) в качестве параметра с использованием сопоставителя. Вот пример кода, который иллюстрирует проблему.

/******************************************************/
import static org.hamcrest.Matchers.is;

import mockit.Expectations;

import org.testng.annotations.Test;

public class PrimitiveMatcherTest {
  private MyClass obj;

  @Test
  public void testPrimitiveMatcher() {
    new Expectations(true) {
      MyClass c;
      {
        obj = c;
        invokeReturning(c.getFoo(with(is(false))), "bas");
      }
    };

    assert "bas".equals(obj.getFoo(false));

    Expectations.assertSatisfied();
  }

  public static class MyClass {
    public String getFoo(boolean arg) {
      if (arg) {
        return "foo";
      } else {
        return "bar";
      }
    }
  }
}
/******************************************************/

Строка, содержащая вызов invokeReturning (...), выдает исключение NullPointerException.

Если я изменю этот вызов, чтобы не использовать сопоставитель, как в:

invokeReturning(c.getFoo(false), "bas");

он работает нормально. Для меня это нехорошо, потому что в моем реальном коде я фактически издеваюсь над многопараметрическим методом, и мне нужно использовать сопоставление для другого аргумента. В этом случае класс Expectations требует, чтобы аргументы все использовали сопоставление.

Я почти уверен, что это ошибка, или, возможно, невозможно использовать Matcher с примитивными типами (это меня огорчило). Кто-нибудь сталкивался с этой проблемой и знает, как ее обойти?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
4
0
3 823
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

проблема заключается в сочетании использования Expectation и того, что Matchers не поддерживает примитивный тип.

Код Matchers полагается на Generic, который в основном не поддерживает примитивный тип. Обычно сопоставления используются больше для сопоставления значений; с функцией автоматической упаковки / распаковки в Java 5 это обычно не проблема.

Но JMockit Expectation не использует его для сопоставления значения, он использует его для какого-то синтаксического анализа, чтобы определить тип сигнатуры вызова метода ... который в этом случае сопоставления приведет к логическому типу, в то время как ваш метод является примитивным типом ... поэтому он не работает издеваться над этим должным образом.

Мне жаль, что я не могу сказать вам никакого обходного пути для этого. Может, кто-нибудь еще может помочь.

Хм, вот чего я и боялся :( Спасибо за ответ

Kris Pruden 18.09.2008 06:05
Ответ принят как подходящий

Итак, проблема, похоже, в Expectations.with ():

   protected final <T> T with(Matcher<T> argumentMatcher)
   {
      argMatchers.add(argumentMatcher);

      TypeVariable<?> typeVariable = argumentMatcher.getClass().getTypeParameters()[0];

      return (T) Utilities.defaultValueForType(typeVariable.getClass());
   }

Вызов typeVariable.getClass () не делает того, чего ожидает автор, а вызов типа Utilities.defaultValueFor возвращает null. Деавтоматический возврат к примитивному логическому значению - вот откуда приходит NPE.

Я исправил это, изменив вызов invokeReturning (...) на:

invokeReturning(withEqual(false)), "bas");

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

Я изменил JMockit (выпуск 0.982), так что «with (is (false))» и другие аналогичные варианты теперь работают должным образом (он больше не возвращает null, а фактическое значение аргумента внутри внутреннего сопоставителя).

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