JMockit 麻烦(刚刚开始)
所以我有一个有点复杂的问题,我将用类似的例子来描述它,而不是复制大量的代码。问题在于我真的不知道如何很好地使用 JMockit,我敢说正确。
我有一个接口:
public interface IRsrcResolver {
RsrcSet getForQuery(Query, RsrcContext, int);
}
它有一个真正的实现 - 它有点紧张。所以我制作了一个仅返回 null 的模拟版本。然后我想设置一个[非严格]期望,它将返回正确的值。它将测试更改为测试。
在代码中:
public class MockRsrcResolver implements IRsrcResolver {
RsrcSet getForQuery(Query, RsrcContext, int) { return null; }
}
在 Test 类中我实现了它,然后想要设置期望(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 获取 null 值,调试显示它调用 null MockRsrcResolver,而不是使用期望... 我这样做是否不正确?感谢您的任何建议!
SO I have a kinda convoluted problem I will describe it with similar examples instead of copying TONS of code in. The problem comes in that I don't really know how to use JMockit well, dare I say properly.
I have an interface:
public interface IRsrcResolver {
RsrcSet getForQuery(Query, RsrcContext, int);
}
There is a real implementation of it - it is kinda intense. So I made a mocked version that just returns null. I want to then set an [nonstrict]expectation that will return the proper values. It changes test to test.
In code:
public class MockRsrcResolver implements IRsrcResolver {
RsrcSet getForQuery(Query, RsrcContext, int) { return null; }
}
in the Test class I implement it and then want set the expectations (StateEngine uses the 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 ... */
}
}
In doSomething there is something like:
IRsrcResolver m_rsrcResolver = new RsrcResolver ()
RsrcSet m_rsrcSet = m_rsrcResolver.getQuery (query, rsrcCtx, 4);
m_rsrcSet.doSomethingElse ();
m_rsrcSet gets a null value and the debug shows it calling into the null MockRsrcResolver, instead of using the expectation...
Am I incorrect in doing it this way? Thanks for any advice you may have!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
JMockit 并不是很容易理解,因为当我们使用它时会发生很多神奇的事情,而且这可能非常不直观(尽管非常强大)。
在您的情况下,类
MockRsrcResolver
似乎没有用,因为您想模拟对RsrcResolver
方法的调用(在测试代码中实例化)。期望的模拟变量被滥用。不应给
rsrcResolver
、rsrcSet
和stateEngine
赋值。它们实际上是 JMockit 神奇生成的模拟实例的占位符。解决方案 1
如果不必模拟
RsrcSet
,下面是我如何模拟此方法:请注意,我将“模拟占位符”变量声明为期望的成员,而不是测试课。也许后者也有效,我不知道(有很多方法可以用 JMockit 达到相同的结果)。但重要的一点是我不会重新分配这些变量。
上述期望意味着:“拦截
RsrcResolver#getForQuery
方法的每次调用并返回queryResult
实例”。实际上,当使用非严格期望(我主要使用严格期望)时,我不确定确切的行为。也许这意味着:“拦截
RsrcResolver
的每个方法的调用,不执行任何操作并返回默认值。但是对于方法RsrcResolver#getForQuery
的特殊情况,返回queryResult
实例。”解决方案 2
如果
RsrcSet#doSomethingElse
也必须被模拟,那么我将如何模拟这个方法:上述期望意味着:“拦截该方法的每个调用
RsrcResolver#getForQuery
> 并返回一个模拟的RsrcSet
实例,该模拟实例在调用时不会执行任何操作”。当然,如果doSomethingElse
必须返回一个值,您可以使用result =
指令。JMockit is not really easy to understand, because there is a lot of magic happening when we use it, and this can be very unintuitive (though very powerful).
In your situation, it appears that the class
MockRsrcResolver
is useless, since you want to mock a call to a method ofRsrcResolver
(which is instanciated in the tested code).There is a misuse of the expectation's mocked variables.
rsrcResolver
,rsrcSet
andstateEngine
should not be given a value. They are actually placeholders for the mocked instances that JMockit magically generates.Solution 1
Here is how I would have mocked this method, if
RsrcSet
doesn't have to be mocked :Note that I declare the "mock placeholder" variables as member of the expectation, not as member of the test class. Maybe the latter works too, I don't know (there are many ways to achieve the same result with JMockit). But the important point is that I don't reassign those variables.
The above expectation means : "intercept every calls of the method
RsrcResolver#getForQuery
and return thequeryResult
instance instead".Actually I'm not sure about the precise behavior, when using non-strict expectations (I mainly use strict ones). Maybe it means : "intercept calls of every methods of
RsrcResolver
, doing nothing and returning default values. But for the special case of methodRsrcResolver#getForQuery
, return thequeryResult
instance."Solution 2
Here is how I would have mocked this method, if
RsrcSet#doSomethingElse
has to be mocked too :The above expectation means : "intercept every calls of the method
RsrcResolver#getForQuery
and return a mockedRsrcSet
instance instead. This mocked instance will do nothing when called". Of course, ifdoSomethingElse
has to return a value, you can use aresult =
instruction.