Java 验证是否创建了临时对象
我在java环境中,使用Mockito(但我不受其约束)满足基本的模拟需求 我有这样的代码Java 验证是否创建了临时对象,java,mocking,mockito,Java,Mocking,Mockito,我在java环境中,使用Mockito(但我不受其约束)满足基本的模拟需求 我有这样的代码 public class AuditInfoSerializer { [..] public Map<String, Object> doStuff(Object a) { doOtherStuff("hello", new TempClass(someField, <someParams>)); doOtherStuff("wo
public class AuditInfoSerializer {
[..]
public Map<String, Object> doStuff(Object a) {
doOtherStuff("hello", new TempClass(someField, <someParams>));
doOtherStuff("world", new TempClass(someField, <otherParams>));
return getResult();
}
}
公共类序列化程序{
[..]
公共地图doStuff(对象a){
doOtherStuff(“你好”,新TempClass(someField,));
doOtherStuff(“世界”,新TempClass(someField,);
返回getResult();
}
}
在一个测试中,我想验证在调用doStuff
方法时是否有两个使用正确参数集创建的TempClass
实例
这可能吗?您不想验证测试对象上的临时数据。您希望模拟依赖项并断言测试行为下的对象:即,通过此输入,您将获得此输出。
模拟验证是模拟方法的一种折衷,模拟方法只会产生副作用,而不返回任何结果。
所以,只有在你没有选择的时候才使用它。
在单元测试中,您需要断言测试方法返回的内容,即
getResult()
使用
Assert.assertEquals(…)
而不是使用Mockito.verify(…)
执行此操作您不想验证测试对象上的临时数据。您希望模拟依赖项并断言测试行为下的对象:即,通过此输入,您将获得此输出。模拟验证是模拟方法的一种折衷,模拟方法只会产生副作用,而不返回任何结果。
所以,只有在你没有选择的时候才使用它。
在单元测试中,您需要断言测试方法返回的内容,即
getResult()
使用
Assert.assertEquals(…)
而不是使用Mockito.verify(…)
这样做在很大程度上我同意@davidxxx关于模拟验证权衡的观点。如果您有一个设置,允许您对结果做出断言,比如作为结果创建的地图,那么就去做吧
从API的角度来看,doStuff
是一种简单直接的方法:向它扔东西,然后拿回东西。您感兴趣的信息将包含在地图中(这将是您的断言)
在doStuff
返回一些东西之前,引擎盖下有很多事情要做。很多人在测试东西时倾向于打破封装。他们一直在寻找揭开幕后真相的方法。我相信这是很自然的。当然,这也是一种反模式。无论您(mis)使用什么工具打破自然边界(模拟框架、自定义反射、“代码库中的后门”等),这都无关紧要。它总是错的。正如@Michael已经指出的,调用doOtherStuff
实际上是一个实现细节。从调用doStuff
的客户机代码的角度来看。它对如何创建地图感兴趣吗?我对此表示怀疑。这也应该是您的测试视角
关于在测试中使用验证的最后一件事。我想缓和一下权衡声明。我真的不喜欢这里的概括。与真实断言相比,验证并不总是不那么吸引人的选择:
// Valid test without any verifaction
@Test
void method_foo_returns_gibberish (@Mock SomeInput someInput) {
// Maybe this is just to prevent an NPE ...
when(someInput.readStuff()).thenReturn("bla");
assertEquals("gibberish", Foo.foo(someInput));
}
// Test made possible by verification
@Test
void method_foo_is_readonly (@Mock SomeInput someInput) {
Foo.foo(someInput);
verify(someInput.readStuff());
verifyNoMoreInteractions(mockedList);
}
这是我能想到的最明显的例子。有一小部分BDD天才努力围绕验证驱动的测试构建他们的整个体系结构
当谈到测试时,大多数情况下,没有黑与白。使用模拟和验证意味着编写不同的测试
和往常一样,这是关于选择正确的工具。在大多数情况下,我同意@davidxxx关于模拟验证权衡的观点。如果您有一个设置,允许您对结果做出断言,比如作为结果创建的地图,那么就去做吧 从API的角度来看,
doStuff
是一种简单直接的方法:向它扔东西,然后拿回东西。您感兴趣的信息将包含在地图中(这将是您的断言)
在doStuff
返回一些东西之前,引擎盖下有很多事情要做。很多人在测试东西时倾向于打破封装。他们一直在寻找揭开幕后真相的方法。我相信这是很自然的。当然,这也是一种反模式。无论您(mis)使用什么工具打破自然边界(模拟框架、自定义反射、“代码库中的后门”等),这都无关紧要。它总是错的。正如@Michael已经指出的,调用doOtherStuff
实际上是一个实现细节。从调用doStuff
的客户机代码的角度来看。它对如何创建地图感兴趣吗?我对此表示怀疑。这也应该是您的测试视角
关于在测试中使用验证的最后一件事。我想缓和一下权衡声明。我真的不喜欢这里的概括。与真实断言相比,验证并不总是不那么吸引人的选择:
// Valid test without any verifaction
@Test
void method_foo_returns_gibberish (@Mock SomeInput someInput) {
// Maybe this is just to prevent an NPE ...
when(someInput.readStuff()).thenReturn("bla");
assertEquals("gibberish", Foo.foo(someInput));
}
// Test made possible by verification
@Test
void method_foo_is_readonly (@Mock SomeInput someInput) {
Foo.foo(someInput);
verify(someInput.readStuff());
verifyNoMoreInteractions(mockedList);
}
这是我能想到的最明显的例子。有一小部分BDD天才努力围绕验证驱动的测试构建他们的整个体系结构
当谈到测试时,大多数情况下,没有黑与白。使用模拟和验证意味着编写不同的测试
一如既往,关键在于选择正确的工具。为什么您会关心是否创建了两个
TempClass
实例?这是一个实现细节。您需要关心的是返回的映射
。至于它是否可能,则完全取决于doOtherStuff
的实现,您尚未提供。在当前状态下,不。测试行为,而不是实现。例如,假设将TempClass
替换为ShinyAwesomeThingy
。只要getResult()
继续返回