26

我对 Mockito 有点陌生,我想知道如何存根获取/设置对。

例如

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

我怎样才能让它们表现得正常:如果我调用的测试中的某个地方setString("something");我想getString()返回“某物”。这是可行的还是有更好的方法来处理这种情况?

4

5 回答 5

41

我还希望 getter 返回最近的 setter 调用的结果。

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));
于 2013-01-24T08:41:39.957 回答
7

I can think of three possible approaches.

  1. Don't use HttpServletRequest directly in your application; make a wrapper class for it, and have an interface for the wrapper class. Wherever you currently use HttpServletRequest in the application, use the interface instead. Then in the test, have an alternative implementation of this interface. Then, you don't need a Mockito mock at all.

  2. Have a field in your test class that stores the value that you have set the String to. Make two Mockito Answer objects; one that returns the value of this field when getString is called, and another that sets the value of this field when setString is called. Make a mock in the usual way, and stub it to use both of these answers.

  3. Make an abstract class (which can be a static inner class of your test class) that implements the HttpServletRequest interface, but has the field that you want to set, and defines the getter and setter. Then mock the abstract class, and pass the Mockito.CALLS_REAL_METHODS in as a default answer. When you call the getter or the setter on the mock, the real method will kick in, which is the behaviour you want.

Hopefully, one of these three alternatives will meet your needs.

于 2012-04-19T06:01:38.040 回答
2

我发现这很好用:

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

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

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

于 2020-10-26T11:31:29.437 回答
0

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

它具有用于基于 Web 的操作的内置模拟。

否则,使用答案为您的模拟对象定义您自己的响应(http://mockito.googlecode.com/svn/branches/1.8.5/javadoc/org/mockito/stubbing/Answer.html

于 2012-04-18T23:14:26.633 回答
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()方法。因此,每当 setter 方法由被测代码执行时,该 setter 的存根将其记录到MutableObject帮助器对象中。然后,getter 实现可以返回这个设置的记录值。

于 2018-05-31T06:08:32.000 回答