1

所以我有一个有点复杂的问题,我会用类似的例子来描述它,而不是复制大量的代码。问题在于我真的不知道如何很好地使用 JMockit,我敢说正确。

我有一个界面:

public interface IRsrcResolver {
 RsrcSet getForQuery(Query, RsrcContext, int);
}

它有一个真正的实现——它有点激烈。所以我制作了一个只返回 null 的模拟版本。然后我想设置一个 [nonstrict] 期望,它将返回正确的值。它将测试更改为测试。

在代码中:

public class MockRsrcResolver implements IRsrcResolver { 
  RsrcSet getForQuery(Query, RsrcContext, int) { return null; } 
}

在测试类中我实现它然后想要设置期望(StateEngine 使用 RsrcResolver)

    public class StateEngineTest {
      @Mocked
      public IRsrcResolver rsrcResolver;
      @Mocked
      public RsrcSet rsrcSet;

      @Mocked
      private StateEngine stateEngine;


      public void setUp () throws Exception {
        stateEngine = new StateEngine ();
        rsrcResolver = new MockRsrcResolver ();
        rsrcSet = new RsrcSet ();

        new NonStrictExpectations () {
          {
            rsrcResolver.getForQuery((Query) any, (RsrcContext)any, anyInt);
            result = rsrcSet;
          }
        }
      }


    @Test
    public void testSetState () {
      /*... does something that calls getForQuery (...) on an IRsrcResolver ...*/
      stateTest.doSomething ();
      /* ... assert assert assert ... */
    }  
  }

在 doSomething 中有类似的东西:

  IRsrcResolver m_rsrcResolver = new RsrcResolver ()
  RsrcSet m_rsrcSet = m_rsrcResolver.getQuery (query, rsrcCtx, 4);
  m_rsrcSet.doSomethingElse ();

m_rsrcSet 得到一个空值,调试显示它调用了空 MockRsrcResolver,而不是使用期望......我这样做是不正确的吗?感谢您的任何建议!

4

1 回答 1

1

JMockit 并不是很容易理解,因为当我们使用它时会发生很多神奇的事情,这可能非常不直观(尽管非常强大)。

在您的情况下,该类似乎MockRsrcResolver没有用,因为您想模拟对方法的调用RsrcResolver(在测试代码中实例化)。

期望的模拟变量存在误用。rsrcResolver,rsrcSet并且stateEngine不应该被赋予一个值。它们实际上是 JMockit 神奇生成的模拟实例的占位符。

解决方案 1

如果不必模拟,我将如何模拟此方法RsrcSet

final RsrcSet queryResult = new RsrcSet();
// (insert initialization of queryResult here)

new NonStrictExpectations () {
  RsrcResolver rsrcResolver;
  {
    rsrcResolver.getForQuery((Query) any, (RsrcContext)any, anyInt);
    result = queryResult
  }
}

请注意,我将“模拟占位符”变量声明为期望的成员,而不是测试类的成员。也许后者也有效,我不知道(有很多方法可以使用 JMockit 达到相同的结果)。但重要的一点是我不会重新分配这些变量。

上述期望意味着:“拦截方法的每次调用RsrcResolver#getForQuery并返回queryResult实例”。实际上,当使用非严格的期望(我主要使用严格的期望)时,我不确定确切的行为。也许它的意思是:“拦截每个方法的调用RsrcResolver,什么都不做,返回默认值。但是对于方法的特殊情况RsrcResolver#getForQuery,返回queryResult实例。”

解决方案 2

如果也必须模拟,这就是我将如何模拟此方法RsrcSet#doSomethingElse

new NonStrictExpectations () {
  RsrcResolver rsrcResolver;
  RsrcSet rsrcSet;
  {
    rsrcResolver.getForQuery((Query) any, (RsrcContext)any, anyInt);
    result = rsrcSet;
    rsrcSet.doSomethingElse();
  }
}

上面的期望意味着:“拦截方法的每次调用RsrcResolver#getForQuery并返回一个模拟RsrcSet实例。这个模拟实例在调用时什么都不做”。当然,如果doSomethingElse必须返回一个值,你可以使用result =指令。

于 2010-09-09T09:33:35.820 回答