Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better Mockito integration #1

Closed
skinny85 opened this issue Jun 24, 2017 · 2 comments
Closed

Better Mockito integration #1

skinny85 opened this issue Jun 24, 2017 · 2 comments

Comments

@skinny85
Copy link
Owner

In "regular" JUnit, you can use the MockitoJUnitRunner to avoid explicitly initializing mocks (among other things - see the JavaDocs linked above for details):

 @RunWith(MockitoJUnitRunner.class)
 public class ExampleTest {

     @Mock
     private List list;

     @Test
     public void shouldDoSomething() {
         list.add(100);
     }
 }

There was a Feature Request to add this capability to Specnaz.

@skinny85
Copy link
Owner Author

Right now, you can save some boilerplate by using MockitoAnnotations.initMocks:

import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.specnaz.junit.SpecnazJUnit;

import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

public class UsingMockitoSpec extends SpecnazJUnit {
    @Mock
    List<String> list;

    {
        describes("A Mockito test", it -> {
            it.beginsEach(() -> {
                MockitoAnnotations.initMocks(this);
            });

            it.should("initialize the mocks correctly", () -> {
                assertThat(list.get(99)).isNull();
            });
        });
    }
}

Whatever design we come up with, I would assume it would do something very similar to above. The question then becomes, is it worth to develop a feature just to save one beginsEach method? (I don't know; this is not a sarcastic question, I'm honestly curious whether it's a good trade-off).

Another thing is that there might be legitimate cases when you want to init the mocks in a beginsAll instead of a beginsEach - the implemented solution would have to allow you to switch between the 2 modes (I would most likely make the beginsEach behavior the default).

Pros of developing this solution:

  • save a little boilerplate

Cons:

  • introduce some (potentially) surprising behavior (it might not be obvious when and how are the mocks being initialized)
  • increased implementation complexity

If we do choose to implement this feature, probably the MockitoSession API would come in handy.

@skinny85
Copy link
Owner Author

skinny85 commented Mar 3, 2018

This has been done, but in a rather different way than I originally planned. It's possible thanks to the JUnit Rules support that has been added in version 1.3.

Example:

public class MockitoExampleSpec extends SpecnazJUnit {
    public Rule<MockitoRule> mockitoRule = Rule.of(() -> MockitoJUnit.rule());

    @Mock
    private List<Integer> listMock;

    {
        describes("Using the JUnit Mockito Rule in Specnaz", it -> {
            it.should("initialize fields annotated with @Mock", () -> {
                when(listMock.get(0)).thenReturn(400 + 56);

                assertEquals(456, (int) listMock.get(0));
            });
        });
    }
}

Because of that, I'm resolving this one.

@skinny85 skinny85 closed this as completed Mar 3, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant