【问题标题】:Using jmockit expectations with matchers and primitive types将 jmockit 期望与匹配器和原始类型一起使用
【发布时间】:2008-09-17 23:43:39
【问题描述】:

我正在使用 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 类要求 所有 参数使用匹配器。

我很确定这是一个错误,或者可能无法将 Matchers 与原始类型一起使用(这会让我感到难过)。有没有人遇到过这个问题,知道如何解决?

【问题讨论】:

    标签: java unit-testing mocking jmockit


    【解决方案1】:

    所以问题似乎出在 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");
    

    我不再在这里使用匹配器,但它足以满足我的需要。

    【讨论】:

      【解决方案2】:

      问题是期望使用和匹配器不支持原始类型的组合。

      Matchers 代码依赖于基本不支持原始类型的 Generic。通常情况下,Matchers 的使用更多是为了匹配值;使用 Java 5 中的自动装箱/拆箱功能,这通常不是问题。

      但是 JMockit 的 Expectation 并没有使用它来匹配值,它使用它来进行某种解析以确定方法调用签名类型。在这种情况下,匹配器将导致布尔类型,而您的方法是原始类型。所以它无法正确模拟它。

      很抱歉,我无法告诉您任何解决方法。也许其他人可以提供帮助。

      【讨论】:

      • 嗯,这就是我害怕的:(谢谢你的回答
      【解决方案3】:

      我更改了 JMockit(版本 0.982),以便“with(is(false))”和其他类似变体现在可以按预期工作(它不再返回 null,而是内部匹配器中的实际参数值)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-05-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-01
        • 2010-10-28
        相关资源
        最近更新 更多