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

WIthMockito feature request #3346

Open
christopher-spires opened this issue May 16, 2024 · 0 comments
Open

WIthMockito feature request #3346

christopher-spires opened this issue May 16, 2024 · 0 comments

Comments

@christopher-spires
Copy link

I was using AssertJ and noticed they had an interface called WithAssertions. Looking at the source, I could see it was an interface with default methods that called static methods. The interface methods were identical to the static methods in regards to parameters and return type. And the implementation was only the call to the static method.

It provided a much easier way to integrate the framework into the tests. Prior to the interface, to use the static method, the class needed to be statically imported. After the interface, the method could be found in autocompletion from the IDE (IJ: crtl-space keyboard shortcut) because it was considered a method of the test class. Never had to worry about importing the incorrect static class/method (i.e. assertThat is in both AssertJ and Junit).

I didn't find this feature in Mockito.

This led to me creating a plugin to auto generate WithMockito/WithAdditionalAnswers/WithArgumentMatchers and had the test classes template implement WithMockito. The challenge of this solution was the default behavior of IntelliJ didn't want to generate-test-sources and would trip up builds after a clean. (the auto-generation wa chosen because the multi-module projects had different mockito dependencies in the sub modules.. don't ask.)

So my thought was: what if Mockito had this feature native in the dependency? A WithMockito interface with default methods that called the static methods. Then the template for test classes could simply implements WithMockito :

  • never have to stop the flow of writing tests to do the static import.
  • autocomplete of "static methods" because they are now class methods.
  • never accidentally import a different frameworks method of the same name.
  • never have to provide all the imports in the test class template only to have them cleaned out on the first optimization of imports.
  • never have to consider using the wildcard import as it commonly goes against coding standards.
  • never have to be concerned that there are too many static imports.
  • usage should lead to more fluent implementations. No reason to use Mockito.mock(...) Matchers.any() etc.

I managed to keep the javadocs since it started with the source files from the dependency.

It wouldn't require any changes to existing implementations. Users could choose to use the feature if they wanted or simply ignore it.

Effectively it would go from something like:

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
// for each static method that is used ... any()/anyString() etc.
import org.junit.jupiter.api.Test;

public class MyServiceTest {

    @Test
    public void testMyService() {
        // Create a mock object for the dependency
        Dependency dependencyMock = mock(Dependency.class);
        // Set up behavior for the mock object
        when(dependencyMock.doSomething()).thenReturn("Mocked result");
        // ... test code
        // Verify that the method under test interacts correctly with the dependency
        verify(dependencyMock).doSomething();
    }
}

To:

import static org.mockito.WithMockito;
import org.junit.jupiter.api.Test;

public class MyServiceTest implements WithMockito {

    @Test
    public void testMyService() {
        // Create a mock object for the dependency
        Dependency dependencyMock = mock(Dependency.class);
        // Set up behavior for the mock object
        when(dependencyMock.doSomething()).thenReturn("Mocked result");
        // ... test code
        // Verify that the method under test interacts correctly with the dependency
        verify(dependencyMock).doSomething();
    }
}

Note: there are no changes to the test implementation. Only a reduction of the number of imports and the addition of the "implements WithMockito"

The challenge is keeping the interfaces and static implementations 1:1 in both method signatures and javadoc.

I don't mind implementing it. If so, I could use suggestions on how to address the challenge of keeping the implementations 1:1. Also would need to probably leverage the MockitoTest and other test classes that test static methods.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant