Skip to content

Commit 46c8a00

Browse files
tastybentoclaude
andcommitted
Add testing guidance to CLAUDE.md for JUnit 5 alongside PowerMock
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 1467bfc commit 46c8a00

1 file changed

Lines changed: 26 additions & 0 deletions

File tree

CLAUDE.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,32 @@ Related projects are checked out as siblings under `~/git/`:
145145

146146
Check these for source before any network fetch.
147147

148+
## Testing
149+
150+
The project uses a mixed test stack:
151+
152+
- **JUnit 4 + PowerMock** — existing tests in `commands/`, `tasks/`, `utils/`, `database/`, and top-level addon/manager tests. These use `@RunWith(PowerMockRunner.class)` and `@PrepareForTest`.
153+
- **JUnit 5 + Mockito** — newer tests in `panel/` package. These use `@ExtendWith(MockitoExtension.class)` with `@MockitoSettings(strictness = Strictness.LENIENT)`.
154+
- Both frameworks coexist via `junit-vintage-engine` which runs JUnit 4 tests on the JUnit 5 platform.
155+
156+
### Writing new JUnit 5 tests alongside PowerMock
157+
158+
PowerMock's MockMaker conflicts with mockito-inline, so **`mockStatic()` and `mockConstruction()` are not available** in JUnit 5 tests. Use these workarounds:
159+
160+
- **Static singletons** (`Bukkit.getServer()`, `BentoBox.getInstance()`): Set via reflection on the private static field. See `PanelTestHelper.setServer()` and `setBentoBoxInstance()` for examples. Always save/restore the previous value in `@BeforeEach`/`@AfterEach`.
161+
- **Final methods** (`JavaPlugin.getServer()` is final): Set the `server` field on the plugin object via reflection walking the class hierarchy. See `PanelTestHelper.setPluginServer()`.
162+
- **Java records** (`ItemTemplateRecord`, `TemplatedPanel.ItemSlot`): Cannot be mocked. Create real instances using their public constructors. For `TemplatedPanel` (which has no public constructor), use `sun.misc.Unsafe.allocateInstance()` then set fields via reflection. See `PanelTestHelper.createItemSlot()`.
163+
- **Varargs methods** (`User.getTranslation(String, String...)`): Use `Mockito.doAnswer().when()` with `Mockito.<String>any()` instead of `when().thenAnswer()`. The `doAnswer` pattern handles varargs correctly. See `PanelTestHelper.setupUserTranslations()`.
164+
165+
### PanelTestHelper
166+
167+
`src/test/java/world/bentobox/challenges/panel/PanelTestHelper.java` is a shared utility for all panel tests. It provides:
168+
- Reflection helpers for Bukkit/BentoBox static fields
169+
- `ItemTemplateRecord` factory methods (`createTemplate`, `createSimpleTemplate`, `createEmptyTemplate`)
170+
- `createItemSlot()` for `TemplatedPanel.ItemSlot` records
171+
- `createBasicChallenge()` for fully-mocked `Challenge` objects
172+
- `setupUserTranslations()` for varargs-safe translation mocking
173+
148174
## Key Dependencies (source locations)
149175

150176
- `world.bentobox:bentobox``~/git/bentobox/src/`

0 commit comments

Comments
 (0)