Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/375.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将值设置为模拟对象,但获取null_Java_Unit Testing_Mocking_Mockito - Fatal编程技术网

Java 将值设置为模拟对象,但获取null

Java 将值设置为模拟对象,但获取null,java,unit-testing,mocking,mockito,Java,Unit Testing,Mocking,Mockito,我有一个简单的类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 na

我有一个简单的类
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;
   }
}
在我的单元测试代码中,我使用

我在mock对象中设置了
name
,但当我调用getter获取名称时,它返回null

这是一个Mockito特定的问题,还是一个被模拟对象不能设置值的约定?为什么呢?模拟对象下面发生了什么?

嗯,是的,
Foo
的实际代码并不重要,因为您正在模拟它。。。Mockito不知道
setName
getName
之间有什么关系。它不假设它应该将参数存储到
setName
并在调用
getName
时返回它。。。它可以做到,但据我所知,它做不到。Mockito提供的mock只允许您指定对其调用方法时发生的情况,并检查稍后调用的内容。您可以模拟对
getName()
的调用,而不是调用
setName
,并指定它应该返回什么


。。。或者你可以直接使用
Foo
,而不是模仿它。不要认为你必须在考试中嘲笑一切。在使用真实类时,只需模拟(或伪造)一些尴尬的事情,例如,因为它使用文件系统或网络。

默认情况下,mockito在模拟对象中的任何方法上都没有行为

你应该这样做:

Foo mockedFoo = Mockito.mock(Foo.class);
when(mockedFoo.getName()).thenReturn("someName");
String name = mockedFoo.getName();

编辑:正如Jon Skeet所提到的,您不需要模拟可以以正常方式进行测试的东西。

我认为,最好理解Mockito对您的参数类做了什么,以及它通过引用源代码返回了什么类型的对象

一般的理解是,模拟对象是一个伪对象(与提供给
mock()
方法的参数类型相同),没有真正的方法实现。因此,基本上,在现实生活中,对模拟对象的方法调用不会发生任何事,而这正是创建模拟对象的目的(我们不希望调用真正的方法)是吗

我们模拟DAO层、LDAP层或其他服务依赖项,因为我们不想调用对实际数据库或服务的调用如果我们希望发生真正的调用,我们不会创建模拟对象。


调用
mockedFoo.setName(“test”)后,理解了真实的事情发生了
mockedFoo.getName()
不正确-在对模拟对象调用方法后不会发生任何事情,而这正是模拟对象实现的目的

要解决知道代码中是否使用指定值调用了setName()方法的问题,请使用Mockito-verify方法

例如:

verify(mockedFoo, times(1)).setName("test");

将验证带有字符串参数“test”的mockedFoo.setName()方法在被测代码中是否只被调用过一次。

某种程度上使用这种方法。我已经为EasyMock写过了,但是对于Mockito,它也可以同样使用

String nameMock = createNiceMock(String.class);
Foo MockedFoo = new Foo();
Foo.setName(nameMock);

EasyMock.expect(Foo.getName()).andReturn(nameMock);

您需要对模拟对象调用实际方法。在(mockedFoo.getName())时使用@Spy

。然后返回(“测试”)
@Tom,我知道这一点,但我想知道为什么我不能直接在模拟对象上设置值,我不是在问如何返回存根函数。因为它是一个模拟对象,它的目的不是存储东西。如果您想创建自己的实例。@Tom,那么现在您回答了我所期望的问题,因此,模拟对象失去了类中设计的函数是一种“约定”。约定?我称之为定义;根据我的经验,人们常常在不应该的时候嘲笑“值对象”类。我过去考虑过的一件事是,当测试试图模拟此类类时,模拟库检测此类类,然后抛出“无效模拟”异常是否是一个好主意。这可能是一个很好的“选择加入”特性(并且不太难实现)。但是,我们不能模拟最终的方法。那我们怎么办case@Sree当前位置这不是这个问题的主题-如果你找不到与你所问内容相符的问题,我建议你问一个新问题。(我强烈怀疑有这样的问题。)在测试中调用when()应该怎么做?
import static org.mockito.mockito.*应该足够了。然后您可能还需要从第一行删除
Mockito.
String nameMock = createNiceMock(String.class);
Foo MockedFoo = new Foo();
Foo.setName(nameMock);

EasyMock.expect(Foo.getName()).andReturn(nameMock);