Junit 在使用JMock的单元测试中未直接调用的模拟方法
我有一个正在测试的方法。在其调用堆栈中,它调用一个DAO,intern使用JDBC与DB聊天。我对知道JDBC层会发生什么并不感兴趣;我已经做了测试,效果非常好 我尝试使用JMock模拟DAO层,因此我可以专注于测试中的这个方法的细节。这是我所拥有的基本资料Junit 在使用JMock的单元测试中未直接调用的模拟方法,junit,jmock,Junit,Jmock,我有一个正在测试的方法。在其调用堆栈中,它调用一个DAO,intern使用JDBC与DB聊天。我对知道JDBC层会发生什么并不感兴趣;我已经做了测试,效果非常好 我尝试使用JMock模拟DAO层,因此我可以专注于测试中的这个方法的细节。这是我所拥有的基本资料 @Test public void myTest() { context.checking(new Expectations() { { allowing(myDAO).g
@Test
public void myTest()
{
context.checking(new Expectations() {
{
allowing(myDAO).getSet(with(any(Integer.class)));
will(returnValue(new HashSet<String>()));
}
});
// Used only to show the mock is working but not really part of this test.
// These asserts pass.
Set<String> temp = myDAO.getSet(Integer.valueOf(12));
Assert.assertNotNull(temp);
Assert.assertTrue(temp.isEmpty());
MyTestObject underTest = new MyTestObject();
// Deep in this call MyDAO is initialized and getSet() is called.
// The mock is failing to return the Set as desired. getSet() is run as
// normal and throws a NPE since JDBC is not (intentionally) setup. I want
// getSet() to just return an empty set at this layer.
underTest.thisTestMethod();
...
// Other assertions that would be helpful for this test if mocking
// was working.
}
@测试
公共无效myTest()
{
上下文检查(新期望值(){
{
允许(myDAO.getSet)(带有(any(Integer.class));
will(returnValue(newhashset());
}
});
//仅用于显示模拟正在工作,但不是此测试的一部分。
//这些断言是通过的。
Set temp=myDAO.getSet(Integer.valueOf(12));
Assert.assertNotNull(临时);
Assert.assertTrue(temp.isEmpty());
MyTestObject underTest=新建MyTestObject();
//在这个调用的深处,MyDAO被初始化,getSet()被调用。
//模拟未能按要求返回集合。getSet()作为
//正常并抛出一个NPE,因为JDBC不是(故意)设置的
//getSet()只返回此层的空集。
underTest.thistTestMethod();
...
//如果进行模拟,则有助于此测试的其他断言
//他在工作。
}
从我创建这个测试所学到的知识来看,我无法使用JMock模拟间接对象。或者我看不到关键点。我希望下半场是真的
想一想,谢谢。从片段中,我猜MyTestObject使用反射或静态方法或字段来获取DAO,因为它没有构造函数参数。JMock不按类型替换对象(现在随时都会有人推荐其他这样做的框架) 这是故意的。JMock的目标是通过要求清晰的依赖关系和集中的行为来突出对象设计的弱点。我发现在域对象中隐藏DAO/JDBC访问最终会让我陷入麻烦。这意味着域对象具有秘密依赖关系,这使得它们更难理解和更改。我更喜欢在代码中明确这些关系 因此,您必须以某种方式将模拟对象放入目标代码中。如果您不能或不想这样做,那么您必须使用另一个框架 还有一点,你可以简化一下测试:
context.checking(new Expectations() {{
allowing(myDAO).getSet(12); will(returnValue(new HashSet<String>()));
}});
context.checking(新期望(){{
允许(myDAO).getSet(12);will(returnValue(newhashset());
}});
在测试中,您应该真正了解期望值并将其输入期望值。这样可以更容易地看到对象之间的值流。在setUp()中,我使用context.mock(myDAO.class)模拟myDAO。在MyTestObject的交互工作中,MyDAO被实例化为“new”。这就是问题所在。你有一个我们看不到的隐式依赖。现在,您必须决定是要使依赖关系显式化,还是使用更聪明的框架进行干预。我想你可以猜到我更喜欢哪一个:)我们选择了JMockit,但也考虑了将PowerMock添加到选项中。我认为你没有抓住重点,但祝你好运