One of ways to create a Mockito mock in Java is to
- create the mock
- stubb the methods.
For instance like this:
// this code is just a imaginary proposal
private Properties emptyProperties() {
Properties myMock = mock(Properties.class); // 1
when(myMock.isEmpty()).thenReturn(true); // 2
when(myMock.size()).thenReturn(0); // 2
return myMock;
}
I would like to create this mock in a fluent way like this:
private Properties emptyProperties() {
return buildMock(Properties.class) // 1
.when(myMock.isEmpty()).thenReturn(true) // 2
.when(myMock.size()).thenReturn(0) // 2
}
Is there any mechanism in Mockito itself which allows to construct mocks like that? Or any other framework which could facilitate this way of construction?
EDIT: Motivation with bigger example.
Answering the comments, my motivation is to create a nested mocks in a fluent way. For instance instead of code:
Questions.QuestionItem item = mock(Questions.QuestionItem.class);
Questions questions = mock(Questions.class);
when(questions.getItems()).thenReturn(Lists.newArrayList(item));
QuestionController controller = mock(QuestionController.class);
when(controller.getQuestions()).thenReturn(questions);
I would like to create something like:
QuestionController controller = mock(QuestionController.class)
.when(getQuestions()).thenReturn(
mock(Questions.class)
.when(getItems()).thenReturn(
Lists.newArrayList(item))
);
One of the motivation is to avoid creating local variables, especially where there are more nesting levels and more methods to mock.
EDIT 2
After using implementation of @knittl the code looks like what I am looking for:
QuestionController demoMock = FluentMock.mock(QuestionController.class)
.when(QuestionController::getQuestions).thenReturn(
FluentMock.mock(Questions.class)
.when(Questions::getItems)
.thenReturn(Lists.newArrayList(
mock(Questions.QuestionItem.class)))
.returnMock())
.returnMock();
I just wonder if there is any library which supports this kind of FluentMock out of the box?
I don't think there's a benefit in avoiding a single line (you are not really saving lines anyway), but if you must do it, the following could be one way to do it. It is a thin wrapper around a Mockito mock object that allows applying a configuration to the mock object, then returns itself.
Usage:
Not sure if that's what you were hoping for.
Alternatively, go full overboard and add all methods (that you need) from
OngoingStubbing:Usage would then look like this:
Caveat: this doesn't allow you to add multiple stubbings to a single method, so you cannot do
when(DemoClass::getName).thenReturn("skynet").thenReturn("T-800")with this kind of fluent builder (you'd have to go thestub(mock -> ...)route or just use plain Mockito)