我一直在使用TestNG
和JMockit
测试我的代码行为一段时间了,我的组合没有具体问题。今天我遇到了一个情况,我需要模仿我的一个内部依赖项,所谓的类型广泛的方式我不需要保持那个模拟,因为没有测试用例处理它直接在他们依靠模拟版本功能时。所以,当然,我把模拟逻辑放在我的@BeforeMethod
中。这是一个示例:
public class SampleTest
{
@Mocked
@Cascading
private InnerDependency dependency;
@BeforeMethod
public void beforeMethod()
{
new NonStrictExpectations()
{
{
dependency.getOutputStream((String)any);
result = new Delegate<OutputStream>()
{
public OutputStream getOutputStream(String url)
{
return null;
}
};
}
};
}
@Test
public void testNormalOperation()
{
// The test whose desired behavior depends on dependency being mocked out
// ..
}
}
但是,由于我的测试并不明确关注模拟的dependency
,我不愿意将它声明为测试类字段,与上面所做的不同。据我所知JMockit
剩下的唯一选择是:
将dependency
声明为本地模拟字段:
new NonStrictExpectations()
{
@Cascading
private InnerDependency dependency;
{
//...
}
}
将dependency
声明为beforeMethod()
的输入参数,类似于对普通@Test
方法所做的操作:
@BeforeMethod
public void beforeMethod(@Mocked @Cascading final InnerDependency dependency)
{
// ...
}
我看到 JMockit 1.6 + 不喜欢第一个选项,并警告WARNING: Local mock field "dependency" should be moved to the test class or converted to a parameter of the test method
。因此,为了让每个人都高兴,我正在推出这个选项。
但是对于第二个选项,TestNG
(当前为6.8.6)在运行测试java.lang.IllegalArgumentException: wrong number of arguments
时抛出异常。在@Test
参数传递正常@Mocked
的情况下,我看不到此行为。即使使用@Parameter
和@Optional
也无济于事(也不应该!)。
那么,有没有办法在不声明不必要的测试类模拟字段的情况下完成这项工作,或者我在这里遗漏了什么?
由于
答案 0 :(得分:1)
只有测试方法(在JUnit或TestNG中使用@Test
注释)支持模拟参数,因此这里唯一的选择是在测试类级别声明模拟字段。
即使没有在任何测试方法中使用,我认为它比在设置方法中声明(使用@Before
,@BeforeMethod
等)更好。如果可能的话,由于设置方法的性质,模拟仍然必须应用于所有测试;拥有测试类的模拟字段可以清楚地了解模拟的范围。
答案 1 :(得分:0)
Dynamic partial mocking是另一种在本地指定@Mocked依赖项的技术。但是,它有它的局限性(见下面的评论)。