Mockito:如何使用getter setter

时间:2012-04-18 20:53:06

标签: java testing mockito

我对Mockito来说是个新手,我想知道如何存根获取/设置对。

例如

public interface Dummy {
     public String getString();
     public void setString(String string);
}

如何使它们正常运行:如果我在调用某个地方调用setString("something");,我希望getString()返回“某事”。这是可行的还是有更好的方法来处理这种情况?

5 个答案:

答案 0 :(得分:30)

我还希望getter返回最近的setter-call的结果。

具有

class Dog
{
    private Sound sound;

    public Sound getSound() {
        return sound;
    }
    public void setSound(Sound sound)   {
        this.sound = sound;
    }
}

class Sound
{
    private String syllable;

    Sound(String syllable)  {
        this.syllable = syllable;
    }
}

我使用以下方法将setter连接到getter:

final Dog mockedDog = Mockito.mock(Dog.class, Mockito.RETURNS_DEEP_STUBS);
// connect getter and setter
Mockito.when(mockedDog.getSound()).thenCallRealMethod();
Mockito.doCallRealMethod().when(mockedDog).setSound(Mockito.any(Sound.class));

答案 1 :(得分:6)

我可以想到三种可能的方法。

  1. 请勿在您的申请中直接使用HttpServletRequest;为它创建一个包装类,并为包装类提供一个接口。无论您当前在应用程序中使用HttpServletRequest,请使用界面。然后在测试中,有一个该接口的替代实现。然后,你根本不需要Mockito模拟。

  2. 在测试类中有一个字段,用于存储您将String设置为的值。制作两个Mockito Answer对象;一个在调用getString时返回该字段的值,另一个在调用setString时设置该字段的值。以通常的方式进行模拟,并将其存根以使用这两种答案。

  3. 创建一个抽象类(可以是测试类的静态内部类),它实现HttpServletRequest接口,但具有您要设置的字段,并定义getter和setter。然后模拟抽象类,并将Mockito.CALLS_REAL_METHODS作为默认答案传递。当您在模拟上调用getter或setter时,真正的方法将启动,这是您想要的行为。

  4. 希望这三种选择中的一种能够满足您的需求。

答案 2 :(得分:0)

在HttpServletRequest存根的这种特殊情况下,我强烈建议使用Spring-Mock框架: (http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/mock/web/package-summary.html

它内置了基于Web的操作模拟。

否则,请使用“答案”为您的模拟对象(http://mockito.googlecode.com/svn/branches/1.8.5/javadoc/org/mockito/stubbing/Answer.html

定义自己的响应

答案 3 :(得分:0)

我有这个问题,但不想接受已接受的答案,因为这样做会停止在我的bean中模拟所有 getter和setter。我想要的只是为一个getter / setter对创建存根,而不是全部。因此,我使用了以下代码。

@Mock
private Dummy mockDummy;
private final MutableObject<String> stringWrapper = new MutableObject<>();

public TestClass() {
    MockitoAnnotations.initMocks(this);

    doAnswer(invocationOnMock -> {
        String injectedString = (String)invocationOnMock.getArguments()[0];
        TestClass.this.stringWrapper.setValue(injectedString);
        return null;
    }).when(this.mockDummy).setString(any());
    when(this.mockDummy.getString()).thenAnswer(
            invocationOnMock -> TestClass.this.stringValue.getValue());
}

第一个lambda实现了Answer<Void>匿名类'answer() method。因此,每当被测试的代码执行setter方法时,该setter的这个存根将其记录到MutableObject辅助对象中。然后,getter实现可以返回已设置的记录值。

答案 4 :(得分:0)

我发现这很好用

doAnswer(answer -> when(dummy.getString()).thenReturn((String) answer.getArguments()[0]))
    .when(dummy).setString(any());

我必须使用doAnswer(..)。when(..),因为setter是void方法。当使用对象调用setter时,将设置getter以响应同一对象。

当您有接口但没有实现时非常有用。