Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.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 非测试方法中创建的对象的模拟非静态方法_Java_Unit Testing_Mocking - Fatal编程技术网

Java 非测试方法中创建的对象的模拟非静态方法

Java 非测试方法中创建的对象的模拟非静态方法,java,unit-testing,mocking,Java,Unit Testing,Mocking,在这种情况下,是否可以使用Mockito、PowerMock或任何其他模拟对象生成器模拟RentalProfile.getStartDate 我试着这样做,但没有成功: @Test public void testsetAmortizationModel() throws Exception { // ... RentalProfile mock = Mockito.mock(RentalProfile.class); Mockito.when(mock.getStart

在这种情况下,是否可以使用Mockito、PowerMock或任何其他模拟对象生成器模拟RentalProfile.getStartDate

我试着这样做,但没有成功:

@Test
public void testsetAmortizationModel() throws Exception {
    // ...
    RentalProfile mock = Mockito.mock(RentalProfile.class);
    Mockito.when(mock.getStartDate()).thenAnswer(new Answer<String>() {
        @Override
        public String answer(InvocationOnMock invocation) throws Throwable {
            return "2014-12-21";
        }
    });
    Mockito.verify(mock);
    // ...

}
还有一个调用RentalProfile.getStartDate的方法。不返回2014-12-21:

public void classMethod() {
    List<RentalProfile> tPaymentPlans =
    aCompositeAgreement.getRentalProfiles().getRentalProfile();
// ...
    for (RentalProfile tRentalProfile : tPaymentPlans) {
        LocalDate tStartDate = BridgeDateUtils.stringWithHyphenToDate(
            tRentalProfile.getStartDate()); // tRentalProfile is RentalProfile object
// ...
}

您发布的代码有几个问题:

正如Vincent所建议的,你可以通过替换Mockito来简化模拟。。。带whenmock.getStartDate.thenReturn2014-12-21

Mockito.verifymock;此处不需要,因为它通常用于检查是否在模拟中调用了具有预期参数的特定方法

在任何地方都没有显示将mock注入到类实例中以方便测试

以下示例类将正确运行并为测试注入依赖项:

public class MyClass {

   private RentalProfile tRentalProfile = null;

   public MyClass(RentalProfile tRentalProfile) {
      this.tRentalProfile = tRentalProfile;
   }

  public void classMethod() {
    // ...
    LocalDate tStartDate = BridgeDateUtils.stringWithHyphenToDate(
      tRentalProfile.getStartDate()); // tRentalProfile is RentalProfile object injected to MyClass
    // ...
  }

}
现在可以用Mockito按以下方式模拟:

@Test
public void testsetAmortizationModel() throws Exception {
    // ...
    RentalProfile mock = Mockito.mock(RentalProfile.class);
    Mockito.when(mock.getStartDate()).thenReturn("2014-12-21");

    MyClass myClass = new MyClass(mock);
    myClass.classMethod();

    // Here you verify whether method has been successfully executed 
    // i.e. verify return value, other class parameters,, mock method calls etc.

}

问题是没有使用在测试中创建的模拟实例

@Test
public void testsetAmortizationModel() throws Exception {
    // ...
    RentalProfile mock = Mockito.mock(RentalProfile.class);
    when(mock.getStartDate()).thenReturn("2014-12-21");
    Mockito.verify(mock);
    // ...

    MyClass classToTest = new MyClass(mock);
    classToTest.myMethod();
}
还有你们班:

public class MyClass {
    private RentalProfile profile;

    public MyClass(RentalProfile profile) { this.profile = profile; }

    public void myMethod() {
        for (RentalProfile tRentalProfile : tPaymentPlans) {
            LocalDate tStartDate = BridgeDateUtils.stringWithHyphenToDate(
                this.profile.getStartDate());
        }
    }
}
您必须解耦变量的创建。您真正想要测试的不是RentalProfile的创建,而是您的方法在返回此值时的反应

在我的示例中,我选择通过构造函数注入概要文件

看看这个问题:
这与问题完全相同:您必须解耦代码。

您可以使用JMockit库模拟在测试代码中创建的对象,如下所示:

@Test
public void testSetAmortizationModel(@Mocked final RentalProfile mock)
{
    new Expectations() {{ mock.getStartDate(); result = "2014-12-21"; }};

    // No need to pass "mock" into the SUT here; any future instance will be mocked.
    MyClass classToTest = new MyClass();
    classToTest.myMethod();
}

您确定您的tRentalProfile与mock是同一个实例吗?如果是同一个实例,它应该可以工作。当您模拟一个类时,您将创建一个必须在测试中使用的模拟实例。它不会修改这个类的所有实例的行为;做了一些编辑。这就是tRentalProfile的创建方式。重点是我测试了另一个类方法,但其中一些方法有本地RentalProfile对象,需要模拟。感谢您的回复,但糟糕的是我只能更改测试代码。顺便说一下,我在我的帖子里犯了一个愚蠢的错误。classMethod具有私有访问类型。如果我使用Whitebox.invokeMethodClass类、Object。。。论据?