Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/363.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 Mockito:模拟私有字段初始化_Java_Mockito_Junit4_Powermockito - Fatal编程技术网

Java Mockito:模拟私有字段初始化

Java Mockito:模拟私有字段初始化,java,mockito,junit4,powermockito,Java,Mockito,Junit4,Powermockito,如何模拟正在内联初始化的字段变量 class Test { private Person person = new Person(); ... public void testMethod() { person.someMethod(); ... } } 在这里,我想在测试Test.testMethod()方法时模拟person.someMethod(),我需要模拟person变量的初始化。有线索吗 编辑:我不允许修改Person

如何模拟正在内联初始化的字段变量

class Test {
    private Person person = new Person();
    ...
    public void testMethod() {
        person.someMethod();
        ...
    }
}
在这里,我想在测试
Test.testMethod()
方法时模拟
person.someMethod()
,我需要模拟
person
变量的初始化。有线索吗


编辑:我不允许修改Person类。

Mockito附带了一个helper类,可以为您保存一些代码:

import org.mockito.internal.util.reflection.Whitebox;

//...

@Mock
private Person mockedPerson;
private Test underTest;

// ...

@Test
public void testMethod() {
    Whitebox.setInternalState(underTest, "person", mockedPerson);
    // ...
}
更新: 不幸的是,mockito团队决定加入mockito 2。因此,您可以重新编写自己的反射样板代码,使用另一个库(例如),或者简单地窃取类(它是)

更新2:
JUnit 5自带了自己的类和类,这些类可能很有用,可以帮助您避免使用另一个库。

我已经找到了这个问题的解决方案,但我忘了在这里发布

@RunWith(PowerMockRunner.class)
@PrepareForTest({ Test.class })
public class SampleTest {

@Mock
Person person;

@Test
public void testPrintName() throws Exception {
    PowerMockito.whenNew(Person.class).withNoArguments().thenReturn(person);
    Test test= new Test();
    test.testMethod();
    }
}
此解决方案的关键点是:

  • 使用PowerMockRunner运行我的测试用例:
    @RunWith(PowerMockRunner.class)

  • 指示Powermock为私有字段的操作准备
    Test.class
    @PrepareForTest({Test.class})

  • 最后模拟Person类的构造函数:

    PowerMockito.mockStatic(Person.class)
    
    PowerMockito.whenNew(Person.class).withNoArguments()。然后返回(Person)


  • 参加聚会已经很晚了,但我在这里被打动了,并得到了一位朋友的帮助。问题是不要使用PowerMock。这适用于Mockito的最新版本

    Mockito附带了这个
    org.Mockito.internal.util.reflection.FieldSetter

    它的基本功能是帮助您使用反射修改私有字段

    这是您使用它的方式:

    @Mock
    private Person mockedPerson;
    private Test underTest;
    
    // ...
    
    @Test
    public void testMethod() {
        FieldSetter.setField(underTest, underTest.getClass().getDeclaredField("person"), mockedPerson);
        // ...
        verify(mockedPerson).someMethod();
    }
    
    通过这种方式,您可以传递模拟对象,然后稍后对其进行验证


    是参考。

    以下代码可用于在REST客户端模拟中初始化映射程序。
    mapper
    字段是私有的,需要在单元测试设置期间进行设置

    import org.mockito.internal.util.reflection.FieldSetter;
    
    new FieldSetter(client, Client.class.getDeclaredField("mapper")).set(new Mapper());
    

    如果需要为所有测试设置相同的变量值,可以使用@Jarda的指南定义该变量:

    @Before
    public void setClientMapper() throws NoSuchFieldException, SecurityException{
        FieldSetter.setField(client, client.getClass().getDeclaredField("mapper"), new Mapper());
    }
    
    但要注意的是,设置不同的私人价值观应该谨慎处理。如果他们是私人的,出于某种原因


    例如,我使用它来更改单元测试中睡眠的等待时间。在真实的例子中,我想睡10秒钟,但在单元测试中,如果是立即的,我会感到满意。在集成测试中,您应该测试实际值。

    如果使用Spring测试,请尝试org.springframework.test.util.ReflectionTestUtils



    此链接可能对您有所帮助。您应该重构代码,以便为
    人员
    传递模拟。选项包括添加构造函数来执行此操作,或添加setter方法。我正在监视我的目标对象是因为其他原因,在这种情况下,当我的对象是spy时,我无法以这种方式设置内部状态。为什么不呢?我用它来对付间谍。创建一个Person实例。存根任何需要存根的内容,然后在您的测试实例上设置它。警告:Whitebox位于
    内部
    包中,在Mockito 2.6.2上似乎不再工作。您可以使用FieldSetter.setField()。我在下面给出了一个同样的例子。@Ralf,因为在Java中更改引用名称总是会导致编译错误。
    FieldSetter
    在Mockito 2.x中不再可用。@Ralf我使用的是版本Mockito-core-2.15.0。在那里可以买到。不过仍然是beta。@RajKumar
    类#getDeclaredField
    接受单个参数,因此paren需要看起来像
    FieldSetter.setField(underTest,underTest.getClass().getDeclaredField(“person”),mockedPerson)。这就是为什么我把它弄错了,并认为在您的示例中修复它可能是一个好主意。谢谢回复。使用内部API不是最好的idea@RajKumar不错,但正如ZimboRodger提到的:使用内部API是个好主意吗?为什么是内针?它对测试非常有用。您的解释谈到了
    mockStatic
    函数,但在您的代码示例中没有说明这一点。代码示例应该有
    mockStatic
    调用,还是构造函数不需要这个调用?太好了!!!非常感谢你!伟大的可能有助于链接到本文,并可能包含需要的依赖项:build.gradle.kts:
    testImplementation(“org.springframework:spring test:5.1.2.RELEASE”)
    Cool,这对我帮助很大,谢谢!这对JUnit5或spring:2.4.2不有用version@SolankiVaibhav为什么不呢?
     ReflectionTestUtils.setField(testObject, "person", mockedPerson);