Java 将值设置为模拟对象但为空
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34205105/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Set value to mocked object but get null
提问by Leem.fin
I have a simple class Foo
to be mocked:
我有一个简单的类Foo
要被嘲笑:
public class Foo {
private String name;
public Foo() {
}
public Foo(String name) {
this.name = name;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
In my unit test code, I mock it by using Mockito.
在我的单元测试代码中,我使用Mockito 来模拟它。
Foo mockedFoo = Mockito.mock(Foo.class);
mockedFoo.setName("test");
// name is null
String name = mockedFoo.getName();
I set name
in mocked object, but when I call getter to get the name it returns null.
我设置name
了模拟对象,但是当我调用 getter 来获取名称时,它返回null。
Is it a Mockito specific issue or is it an convention that mocked object can't set value? Why is that? What is happening underneath with mocked object?
它是 Mockito 特定问题还是模拟对象无法设置值的约定?这是为什么?模拟对象下面发生了什么?
采纳答案by Jon Skeet
Well yes - the actualcode of Foo
doesn't matter, because you're mocking it... and Mockito doesn't know there's meant to be a relationship between setName
and getName
. It doesn't assume that it should store the argument to setName
and return it when getName
is called... it coulddo that, but it doesn't as far as I'm aware. The mock provided by Mockito just allows you to specify what happens when methods are called on it, and check what wascalled later on. Instead of calling setName
, you could mock a call to getName()
and specify what it should return...
嗯,是的 - 的实际代码Foo
并不重要,因为你在嘲笑它......而 Mockito 不知道setName
和之间存在关系getName
。它不假设它应该存储参数setName
并在getName
调用时返回它......它可以做到这一点,但据我所知,它并没有。通过提供的Mockito模拟只允许您指定的方法被调用它会发生什么,并检查什么是所谓的以后。setName
您可以模拟调用getName()
并指定它应该返回的内容,而不是调用...
... or you could just use Foo
directly instead of mocking it. Don't think you have to mock everythingin your tests. Just mock (or fake) things that are awkward when you're using the real class, e.g. because it uses the file system or network.
...或者你可以直接使用Foo
而不是嘲笑它。不要认为您必须在测试中模拟所有内容。当你使用真正的类时,只是模拟(或伪造)那些很尴尬的东西,例如,因为它使用文件系统或网络。
回答by Martin Hansen
By default mockito has no behavior, on any methods in the mocked object.
默认情况下,mockito 在模拟对象中的任何方法上都没有行为。
You should do something like this:
你应该做这样的事情:
Foo mockedFoo = Mockito.mock(Foo.class);
when(mockedFoo.getName()).thenReturn("someName");
String name = mockedFoo.getName();
edit: as mentioned by Jon Skeet, you should not need to mock things that can just be tested in a normal fashion.
编辑:正如 Jon Skeet 所提到的,您不需要模拟可以正常方式测试的东西。
回答by Sabir Khan
I think, its better to understand as what Mockitodoes to your argument class and what kind of object it returns by referring to source code , Mockito Source
我认为,最好通过参考源代码Mockito Source来理解Mockito对您的参数类做了什么以及它返回了什么样的对象
General understanding is that a mocked object is a fake object ( of same type as argument provided to mock()
method ) with no real method implementations.So basically, nothing happens in real life for a method call on mocked object - and that is the very purpose of creating a mocked object ( that we don't wish to call real methods ) , isn't it?
一般的理解是,模拟对象是一个假对象(与提供给mock()
方法的参数类型相同),没有真正的方法实现。所以基本上,在现实生活中对模拟对象的方法调用不会发生任何事情 - 这就是创建一个模拟对象(我们不想调用真正的方法),不是吗?
We mock DAO layer, LDAP layer or other service dependencies because we don't want to invoke calls to actual DB or services. If we want real calls to happen, we would not create mocked objects.
我们模拟 DAO 层、LDAP 层或其他服务依赖项,因为我们不想调用对实际 DB 或服务的调用。如果我们想要真正的调用发生,我们就不会创建模拟对象。
Understanding to have something real have happened after calling mockedFoo.setName("test");
OR mockedFoo.getName();
is incorrect - Nothing happens after you call a method on a mocked object and that is the purpose of mocked object which it is fulfilling.
理解在调用mockedFoo.setName("test");
OR之后发生了一些真实的事情mockedFoo.getName();
是不正确的 - 在对模拟对象调用方法后什么也没有发生,这就是模拟对象正在实现的目的。
回答by David George
To solve your problem of knowing whether the setName() method was called in your code with the specified value use the Mockito verify method.
要解决您知道是否在您的代码中使用指定值调用了 setName() 方法的问题,请使用 Mockito verify 方法。
For example:
例如:
verify(mockedFoo, times(1)).setName("test");
Will verify that the mockedFoo.setName() method with the String parameter "test" was called exactly once in the code under test.
将验证带有字符串参数“test”的 mockedFoo.setName() 方法在被测代码中被调用了一次。
回答by Vishal Sheth
Somewhat this kind of approach is to used. I have written for EasyMock but with Mockito it can also be used as same.
有点用这种方法。我已经为 EasyMock 编写了代码,但是对于 Mockito,它也可以同样使用。
String nameMock = createNiceMock(String.class);
Foo MockedFoo = new Foo();
Foo.setName(nameMock);
EasyMock.expect(Foo.getName()).andReturn(nameMock);