Я использую 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 с примитивными типами (это меня огорчило). Кто-нибудь сталкивался с этой проблемой и знает, как ее обойти?




проблема заключается в сочетании использования Expectation и того, что Matchers не поддерживает примитивный тип.
Код Matchers полагается на Generic, который в основном не поддерживает примитивный тип. Обычно сопоставления используются больше для сопоставления значений; с функцией автоматической упаковки / распаковки в Java 5 это обычно не проблема.
Но JMockit Expectation не использует его для сопоставления значения, он использует его для какого-то синтаксического анализа, чтобы определить тип сигнатуры вызова метода ... который в этом случае сопоставления приведет к логическому типу, в то время как ваш метод является примитивным типом ... поэтому он не работает издеваться над этим должным образом.
Мне жаль, что я не могу сказать вам никакого обходного пути для этого. Может, кто-нибудь еще может помочь.
Итак, проблема, похоже, в 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, а фактическое значение аргумента внутри внутреннего сопоставителя).
Хм, вот чего я и боялся :( Спасибо за ответ