Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
1113683
Update plugin version to 1.8.0
picimako Jul 7, 2026
c6264ce
Remove some comments from build.gradle.kts
picimako Jul 7, 2026
673b9ff
Improve the documentation on base test classes
picimako Jul 7, 2026
419734d
Update action test to validate action result against entire test file…
picimako Jul 7, 2026
16750de
Introduce quick fix test convenience method, rename some methods and …
picimako Jul 7, 2026
8a2365c
Introduce and use convenience methods for some of the test fixture calls
picimako Jul 7, 2026
cae88d6
Update Mockito Javadoc web links in code and other documentation
picimako Jul 7, 2026
19f2359
Convert Mockito v3 and v4 specific test to v5 where possible
picimako Jul 7, 2026
40f5fa2
Move class type analysis after interface check in NotExtensibleClassI…
picimako Jul 8, 2026
ce0a86c
Extract Matchers qualifier replacement and get rid of quick fix insta…
picimako Jul 8, 2026
d09695b
Extract common parts of reference replacer quick fixes
picimako Jul 8, 2026
716a5d6
Deduplicate logic in ModuleDependencyHelper and move the class into t…
picimako Jul 8, 2026
e090e8b
Extract first argument text retrieval
picimako Jul 8, 2026
bf68f0d
Reduce visibility of CallChainAnalyzers
picimako Jul 8, 2026
851aea6
Move EnforecConventionUtil closer to where it is actually used
picimako Jul 8, 2026
5a15d9b
Update ModuleDependencyHelper import references
picimako Jul 8, 2026
85ac6bd
Replace quick fix getName() override with @Getter annotation
picimako Jul 8, 2026
e49b3c7
Move a couple more classes into packages that are closer to where the…
picimako Jul 8, 2026
ea6b11b
Move some suitable classes to the dsl package
picimako Jul 8, 2026
1437c77
Extract CallMatcher from EnforceConventionInspection
picimako Jul 9, 2026
3039236
Move methods from ExceptionUtil to the corresponding inspection class
picimako Jul 9, 2026
a3e0919
Move back MockitoolsContainerUtil to the util package
picimako Jul 9, 2026
310ba7b
Get rid of Optional in ThrowsCheckedExceptionStubbingInspection
picimako Jul 9, 2026
90008fc
Get rid of CallMatcher.anyOf() creation in InconsistentArgumentMatche…
picimako Jul 9, 2026
93e71f6
Retrieve method calls in StubbingAndMethodReturnTypeMismatchInspectio…
picimako Jul 9, 2026
ea4bd12
Replace Stream.noneMatch() with simpler utility call
picimako Jul 9, 2026
b220b36
Remove PublicField suppressions
picimako Jul 9, 2026
3c0d9d0
Merge if statements in SingleInOrderVerificationInspection
picimako Jul 9, 2026
0db7ca0
Deduplicate CallMatcher creation in TimesVerificationModeInspection
picimako Jul 9, 2026
4324c5d
Replace some Stream chains with ContainerUtil calls
picimako Jul 9, 2026
08d301a
Deduplicate computeBlocking() calls in ConversionIntentionBase and im…
picimako Jul 10, 2026
364814b
Compact gradle build configuration
picimako Jul 10, 2026
e9912ae
Make StubbingApproach somewhat more readable
picimako Jul 10, 2026
cd6e052
Make ConvertStubbingAction package-private, and don't expose the 'to'…
picimako Jul 13, 2026
eda2220
Simplify ConvertVerificationActionBase
picimako Jul 14, 2026
35d4f4d
Replace the arguments of some verification conversion actions with Ve…
picimako Jul 14, 2026
dd68ae9
Reduce the number of CallMatcher creations in ConvertMockedStaticVeri…
picimako Jul 14, 2026
7a7046b
Simplify constructor in ConvertVerificationIntentionBase
picimako Jul 14, 2026
d8f2e3e
Make the performConversion() methods of some actions more readable
picimako Jul 14, 2026
38d4bcc
Remove usage of Iterables.getLast()
picimako Jul 14, 2026
922b05b
Delete the TokenTypes utility
picimako Jul 14, 2026
ae1b01e
Replace String.format() with String.formatted()
picimako Jul 14, 2026
f3b56b8
Simplify ConvertCallToFieldIntentionBase
picimako Jul 14, 2026
78d15d6
Deduplicate CallMatcher creation in ConvertMockCallToFieldIntention
picimako Jul 14, 2026
b9ad971
Simplify field and call conversion intentions. Reduce ReadAction usag…
picimako Jul 14, 2026
2fe2d45
Dedulicate list popup display in ListPopupHelper
picimako Jul 14, 2026
28ce5d2
Add the @TestFactory and @ParameterizedTest annotations to list of re…
picimako Jul 14, 2026
034c1a3
Reduce CallMatcher instance creation in VerificationApproach
picimako Jul 14, 2026
ca504df
Add a missing license header
picimako Jul 14, 2026
1b0cf90
Improve code documentation, adjust visibility modifiers, add nullabil…
picimako Jul 14, 2026
cedebed
Rename MockitoolsBaseInspection to MockitoolsInspectionBase
picimako Jul 14, 2026
07c7de3
Rename base quick fix classes to be consistent
picimako Jul 14, 2026
243cab8
Delete FUNDING.yml
picimako Jul 14, 2026
2595872
Update the contribution guide
picimako Jul 14, 2026
3a34991
Update inspection descriptions
picimako Jul 14, 2026
401be78
Add changelog for v1.8.0
picimako Jul 14, 2026
fdb76cd
Suppress an inspection report
picimako Jul 14, 2026
8f3ac5f
Reformat the plugin.xml for better readability
picimako Jul 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .github/FUNDING.yml

This file was deleted.

7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@

## [Unreleased]

## [1.8.0]
### Changed
- Various minor code improvements and cleanups.
- Improved the code documentation and inspection descriptions.

## [1.7.0]
### Changed
- New supported IDE version range: 2026.1 and later.
Expand Down Expand Up @@ -92,7 +97,7 @@ and marked falsely.
- [#53](https://github.com/picimako/mockitools/issues/53): Added an inspection to report when the mocked type and the type of the spied instance don't match in a `mock(Type.class, withSettings().spiedInstance(...));`-type mock creation.
- [#56](https://github.com/picimako/mockitools/issues/56): Added an inspection to report spying on mock objects, i.e. `Mockito.spy(Mockito.mock(...))` and `Mockito.spy(<object annotated with @Mock>)`.
- [#57](https://github.com/picimako/mockitools/issues/57): Added an inspection to report arguments passed into `Mockito.mock()` and `Mockito.spy()` which are designed to determine the mock type based on
the variable's type they are assigned to, and not by the type passed into them. See [Mocking/spying without specifying class](https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#54).
the variable's type they are assigned to, and not by the type passed into them. See [Mocking/spying without specifying class](https://javadoc.io/doc/org.mockito/mockito-core/latest/org.mockito/org/mockito/Mockito.html#54).
- [#58](https://github.com/picimako/mockitools/issues/58): Added an inspection to report `MockSettings`-based mock creations that have convenience methods or simpler variants to create the mock.
- [#59](https://github.com/picimako/mockitools/issues/59): Added an intention action to expand simple mock and spy creation calls to use specific `MockSettings`,
for example `Mockito.mock(<type>, <answer>)` is converted to `Mockito.mock(<type>, Mockito.withSettings().defaultAnswer(<answer>))`.
Expand Down
121 changes: 75 additions & 46 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,84 +1,113 @@
# Developer Documentation

## Technology stack
## Technology Stack

This project builds on the [IntelliJ Platform Plugin Template](https://github.com/JetBrains/intellij-platform-plugin-template) that uses
Gradle as its build system, GitHub Actions for the CI/CD pipeline, and Java 17.
This project builds on the [IntelliJ Platform Plugin Template](https://github.com/JetBrains/intellij-platform-plugin-template)
Gradle as its build system, GitHub Actions for the CI/CD pipeline, and Java/Kotlin for coding.

## Environment setup
### Libraries

- Production: Lombok
- Testing: JUnit 5, AssertJ

## Environment Setup

### JDK

Install Java JDK 17 and configure the project to use that JDK if not automatically configured.
Install Java JDK 21 and configure the project to use that JDK if not automatically configured.

### Setup Mockitools

To start development, just clone this repository to your machine, import the project, let it build, and you should be good to go.
To start development, clone this repository to your machine, import the project, let it build, and you should be good to go.

There are predefined run configurations coming from the platform plugin template you can use to build, test and run the plugin.
There are predefined run configurations coming from the platform plugin template you can use to build, test and run the plugin:

### Suggested plugins for development
| Run Configuration | CLI command | Purpose |
|-------------------------|--------------------------|------------------------------------------------------------------|
| **Run Build** | `./gradlew buildPlugin` | Compiles the project and builds the plugin .jar and .zip archive |
| **Run IDE with Plugin** | `./gradlew runIde` | Runs a sandbox IDE with the Mockitools plugin installed in it |
| **Run Tests** | `./gradlew check` | Runs all tests in the project |
| **Run Verifications** | `./gradlew verifyPlugin` | Runs the Plugin Verifier |

the following plugins are recommended to help with the plugin development:
### Suggested Plugins for Development

The following plugins can help with the plugin development:
- [PsiViewer](https://plugins.jetbrains.com/plugin/227-psiviewer) for inspecting the syntax tree (PSI) of files,
- [Concise AssertJ Optimizing Nitpicker (Cajon)](https://plugins.jetbrains.com/plugin/12195-concise-assertj-optimizing-nitpicker-cajon-) for working with AssertJ assertions.
- [Concise AssertJ Optimizing Nitpicker (Cajon)](https://plugins.jetbrains.com/plugin/12195-concise-assertj-optimizing-nitpicker-cajon-) for working with AssertJ assertions in tests.
- [Just Kitting](https://plugins.jetbrains.com/plugin/21139-just-kitting) for extra utilities for plugin development,
and for easier comparison of configuration files with their versions in the upstream template.

## Project Structure

## Base classes
```
<root>/
└── .github/
└── workflows/ //GitHub Actions workflow files
├── .run/ //IntelliJ Run Configurations
├── docs/ //Project documentation
├── gradle/ //Gradle wrapper files
└── libs.versions.toml //Gradle version catalog
└── src/
├── ...
└── test/
├── ...
└── testData/ //Test data files for inspections, intentions, etc.
```

There are a few base classes that can be used to implement the different plugin features:
- [MockitoolsBaseInspection](src/main/java/com/picimako/mockitools/inspection/MockitoolsBaseInspection.java) for inspections (not all inspections use this as base class)
- [MigrationAidBase](src/main/java/com/picimako/mockitools/inspection/migrationaids/v4/MigrationAidBase.java) for migration aids inspections
### Mockito DSL

## Mockito DSL types
Functionality is organized into and around DSL specific classes in the `com.picimako.mockitools.dsl` package.

Functionality is organized into DSL specific classes:
- classes in the `com.picimako.mockitools.dsl` package
- [StubbingApproach](src/main/java/com/picimako/mockitools/StubbingApproach.java)
- [VerificationApproach](src/main/java/com/picimako/mockitools/VerificationApproach.java)
- [StubType](src/main/java/com/picimako/mockitools/StubType.java)
### Base Classes

## Message bundle
There are a few common base classes that can be used to implement the different plugin features. They are all named
consistently with their names ending with `Base`, e.g. `MockitoolsInspectionBase` or `QuickFixBase`.

Most messages that appear on the UI, in settings, in inspection messages, are stored in a message bundle called `MockitoolsBundle.properties`.
### Message Bundle

Most messages that appear on the UI, in settings, in inspection messages, etc. are stored in a message bundle called `MockitoolsBundle.properties`.
Some messages, like inspection titles are not yet included, and simply are in the plugin.xml.

## Since-version
### Integration Tests

The following markers are placed on extension point implementations and more important types, to help identify certain aspects of the code:
- `@since <version number>` in javadocs
Integration tests build on JUnit 5-based platform test classes. There are a couple of base test classes that are
consistently named as `*TestBase`, e.g. `MockitoolsTestBase`.

## CI/CD
#### JDK

For CI/CD, GitHub Actions is integrated, and workflows are available in the `.github/workflows` folder.
Tests and test bases that are dedicated to testing primarily Java test data files require either a mock JDK from
the IntelliJ Platform or a real JDK to be available.

## Functional tests
This project is configured to always use a real JDK due to former issues and test failures when using a mock JDK.

Functional tests build mostly on JUnit3-based platform test classes. For assertions, either the IntelliJ platform's underlying logic is used, or AssertJ
where applicable.
#### Load 3rd-party Libraries

Mockitools base test classes:
- [MockitoolsTestBase](src/test/java/com/picimako/mockitools/MockitoolsTestBase.java) as the common base test class
- [MockitoolsInspectionTestBase](src/test/java/com/picimako/mockitools/inspection/MockitoolsInspectionTestBase.java) for inspections
- [MockitoolsIntentionTestBase](src/test/java/com/picimako/mockitools/intention/MockitoolsIntentionTestBase.java) for intention actions
- [MockitoolsCodeCompletionTestBase](src/test/java/com/picimako/mockitools/completion/MockitoolsCodeCompletionTestBase.java) for completion contributors
Since the test data files are Java files, certain libraries have to be added to the tests' classpath.

Other resources: [IntelliJ Platform Plugin SDK - Testing Overview](https://plugins.jetbrains.com/docs/intellij/testing-plugins.html)
The necessary libraries are collected in the `ThirdPartyLibrary` enum with their Maven coordinates,
and can be configured in tests via the constructor of `MockitoolsTestBase`.

### Load 3rd-party libs
#### Test Data

#### JDK
Test data files are stored in the `src/test/testData` folder.
They can be configured as project roots via the `@TestDataPath` annotation on test classes.

## CI/CD

For CI/CD, GitHub Actions is integrated, and workflows are available in `.github/workflows/build.yml`.

## Documentation

### General

Java file based tests require either a mock or a real JDK to be available. This project is configured to always use a real JDK,
so that modification of the
[`idea.home.path` system property](https://plugins.jetbrains.com/docs/intellij/code-inspections.html#inspection-unit-test)
is not necessary for running tests locally. And, using the JAVA_HOME based JDK also works on GitHub Actions.
General documentation is stored in the `/docs` root-level folder.

### testData
### Since-version

The `src/test/testData` folder is used to store test data. They can be configured as project roots when setting the test data path in functional tests.
The `@since <version number>` Javadoc tag is placed on extension point implementations and more important types and methods
to help see which version introduced the feature.

## JetBrains resources
- [IntelliJ Platform Plugin SDK](https://plugins.jetbrains.com/docs/intellij/welcome.html)
- [IntelliJ Platform Plugin Template](https://github.com/JetBrains/intellij-platform-plugin-template)
- [JetBrains Community Support](https://intellij-support.jetbrains.com/hc/en-us/community/topics)
- [Request invitation for JetBrains Slack](https://plugins.jetbrains.com/slack)
- [JetBrains Platform - community forum](https://platform.jetbrains.com)
48 changes: 17 additions & 31 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,57 +3,50 @@ import org.jetbrains.changelog.markdownToHTML
import org.jetbrains.intellij.platform.gradle.TestFrameworkType

plugins {
id("java") // Java support
alias(libs.plugins.kotlin) // Kotlin support
alias(libs.plugins.intelliJPlatform) // IntelliJ Platform Gradle Plugin
alias(libs.plugins.changelog) // Gradle Changelog Plugin
alias(libs.plugins.lombok) // Lombok
id("java")
alias(libs.plugins.kotlin)
alias(libs.plugins.intelliJPlatform)
alias(libs.plugins.changelog)
alias(libs.plugins.lombok)
}

group = providers.gradleProperty("pluginGroup").get()
version = providers.gradleProperty("pluginVersion").get()

// Set the JVM language level used to build the project.
kotlin {
jvmToolchain(21)
}
kotlin { jvmToolchain(21) }

// Configure project's dependencies
repositories {
mavenCentral()
// IntelliJ Platform Gradle Plugin Repositories Extension - read more: https://plugins.jetbrains.com/docs/intellij/tools-intellij-platform-gradle-plugin-repositories-extension.html
intellijPlatform {
defaultRepositories()
}
intellijPlatform { defaultRepositories() }
}

dependencies {

//Testing

//Required for 'junit.framework.TestCase' referenced in 'com.intellij.testFramework.UsefulTestCase'
testImplementation(libs.junit)
testImplementation(libs.assertj)
testImplementation(libs.junitJupiterApi)
setOf(
//Required for 'junit.framework.TestCase' referenced in 'com.intellij.testFramework.UsefulTestCase'
libs.junit,
libs.assertj,
libs.junitJupiterApi,
libs.junitJupiterParams,
libs.junitPlatformLauncher,
).forEach(::testImplementation)
testRuntimeOnly(libs.junitJupiterEngine)
testImplementation(libs.junitJupiterParams)
testImplementation(libs.junitPlatformLauncher)

// IntelliJ Platform Gradle Plugin Dependencies Extension - read more: https://plugins.jetbrains.com/docs/intellij/tools-intellij-platform-gradle-plugin-dependencies-extension.html

intellijPlatform {
create(providers.gradleProperty("platformType"), providers.gradleProperty("platformVersion"))

// Plugin Dependencies. Uses `platformBundledPlugins` property from the gradle.properties file for bundled IntelliJ Platform plugins.
bundledPlugins(providers.gradleProperty("platformBundledPlugins").map { it.split(',') })

// Plugin Dependencies. Uses `platformPlugins` property from the gradle.properties file for plugin from JetBrains Marketplace.
plugins(providers.gradleProperty("platformPlugins").map { it.split(',') })

pluginVerifier()
zipSigner()
testFramework(TestFrameworkType.Platform)
//Required for 'LightJavaCodeInsightFixtureTestCase5'
testFramework(TestFrameworkType.Plugin.Java)
testFramework(TestFrameworkType.JUnit5)
}
Expand Down Expand Up @@ -91,17 +84,10 @@ intellijPlatform {
}
}

ideaVersion {
sinceBuild = providers.gradleProperty("pluginSinceBuild")
// untilBuild = providers.gradleProperty("pluginUntilBuild")
}
ideaVersion { sinceBuild = providers.gradleProperty("pluginSinceBuild") }
}

pluginVerification {
ides {
recommended()
}
}
pluginVerification { ides { recommended() } }
}

// Configure Gradle Changelog Plugin - read more: https://github.com/JetBrains/gradle-changelog-plugin
Expand Down
2 changes: 1 addition & 1 deletion docs/argument_matching_capture.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ The following ways of stubbing are supported by this inspection:
- `Mockito.when()`, `BDDMockito.given()`, `Mockito.do...().when()`, matchers in `AdditionalMatchers`

You can find more information in the official documents and source code:
- [Argument matchers documentation](https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#argument_matchers)
- [Argument matchers documentation](https://javadoc.io/doc/org.mockito/mockito-core/latest/org.mockito/org/mockito/Mockito.html#argument_matchers)
- [ArgumentMatchers javadoc](https://javadoc.io/static/org.mockito/mockito-core/3.11.2/org/mockito/ArgumentMatchers.html)
- [org.mockito.internal.exceptions.Reporter#invalidUseOfMatchers(int, List)](https://github.com/mockito/mockito/blob/main/src/main/java/org/mockito/internal/exceptions/Reporter.java)
- [org.mockito.internal.exceptions.Reporter#incorrectUseOfAdditionalMatchers(String, int, Collection)](https://github.com/mockito/mockito/blob/main/src/main/java/org/mockito/internal/exceptions/Reporter.java)
Expand Down
4 changes: 2 additions & 2 deletions docs/mock_creation.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ and validates test code regardless of the Mockito version.

![](https://img.shields.io/badge/inspection-orange) ![](https://img.shields.io/badge/since-0.11.0-blue) [![](https://img.shields.io/badge/implementation-GenericInferredMockAndSpyCreationInspection-blue)](../src/main/java/com/picimako/mockitools/inspection/mocking/GenericInferredMockAndSpyCreationInspection.java)

[Mockito 4.9.0](https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#mock_without_class) introduced an enhancement to `Mockito.mock()` and `Mockito.spy()`
[Mockito 4.9.0](https://javadoc.io/doc/org.mockito/mockito-core/latest/org.mockito/org/mockito/Mockito.html#mock_without_class) introduced an enhancement to `Mockito.mock()` and `Mockito.spy()`
based mock/spy creation, so that the mock type is not determined by the class passed in, instead by the type of the variable/field it is assigned to.

These variants of `mock()` and `spy()` throw an exception if objects other than configuration are passed in, thus this inspection reports
Expand Down Expand Up @@ -166,7 +166,7 @@ class MockSpiedInstanceTypeMismatch {

![](https://img.shields.io/badge/inspection-orange) ![](https://img.shields.io/badge/since-0.1.0-blue) [![](https://img.shields.io/badge/implementation-CallOnMockitoResetInspection-blue)](../src/main/java/com/picimako/mockitools/inspection/CallOnMockitoResetInspection.java)

Based on Mockito's documentation on [resetting mocks](https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#resetting_mocks)
Based on Mockito's documentation on [resetting mocks](https://javadoc.io/doc/org.mockito/mockito-core/latest/org.mockito/org/mockito/Mockito.html#resetting_mocks)

> Smart Mockito users hardly use this feature because they know it could be a sign of poor tests. Normally, you don't need to reset your mocks, just create new mocks for each test method.

Expand Down
2 changes: 1 addition & 1 deletion docs/verifications.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ Mockito.verify(mockObject, timeout(6000)).method(); //over threshold, since 5000
This inspection reports `Mockito.times()` calls whether they can be optimized or deleted based on their argument values.

- `times(0)` can be replaced with `Mockito.never()` for better readability,
- `times(1)` can be removed since 1 is the default value when using `times()` verification. See [Mockito exact verification](https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#exact_verification) documentation.
- `times(1)` can be removed since 1 is the default value when using `times()` verification. See [Mockito exact verification](https://javadoc.io/doc/org.mockito/mockito-core/latest/org.mockito/org/mockito/Mockito.html#exact_verification) documentation.
- `Mockito.times(1)` calls are reported only when they have no sequent calls on them, thus `Mockito.times(1).description("message")` would not be reported.

Both of them can be enabled/disabled on the inspection's settings panel.
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pluginGroup = com.picimako.mockitools
pluginName = Mockitools
pluginRepositoryUrl = https://github.com/picimako/mockitools
# SemVer format -> https://semver.org
pluginVersion = 1.7.0
pluginVersion = 1.8.0

# Supported build number ranges and IntelliJ Platform versions -> https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html
pluginSinceBuild = 261
Expand Down
Loading