繁体   English   中英

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

[英]mock non static method of object which is created not in test method

在这种情况下,是否可以使用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
// ...
}

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

  1. 正如文森特(Vincent)建议的那样,您可以通过将Mockito.when(...).thenAnswer(...)替换为when(mock.getStartDate()).thenReturn("2014-12-21")

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

  3. 您无处显示该模拟已注入您的类实例中以方便测试。

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

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 ,而是返回值时您的方法会做出反应。

在我的示例中,我选择通过构造函数注入配置文件。

看一下这个问题: https : //stackoverflow.com/a/25135757/2015239完全一样的问题:您必须解耦代码。

您可以使用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();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM