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

Using @InjectSpy from a JUnit5 @Nested inner class leads to unreliable test result #32383

Closed
lbilger opened this issue Apr 3, 2023 · 5 comments · Fixed by #32603
Closed

Using @InjectSpy from a JUnit5 @Nested inner class leads to unreliable test result #32383

lbilger opened this issue Apr 3, 2023 · 5 comments · Fixed by #32603
Assignees
Labels
Milestone

Comments

@lbilger
Copy link

lbilger commented Apr 3, 2023

Describe the bug

When I structure my tests in @Nested inner classes, the @InjectSpy annotation from the quarkus-junit5-mockito extension does not work as expected. It seems the annotation is processed twice, creating two spy instances. Then it becomes non-deterministic which of these two instances is injected into the application code. If the instance that the application gets is not the one that the test gets, mocking and/or verification will obviously fail.

Expected behavior

Only one spy is created.

Actual behavior

Multiple spies are created and it is non-deterministic which one is used. The test becomes flaky.

How to Reproduce?

@Path("/hello")
class ExampleResource(val exampleService: ExampleService) {
    @GET fun hello() = exampleService.hello()
}

@ApplicationScoped
class ExampleService {
    fun hello() = "Hello"
}

@QuarkusTest
class ExampleResourceTest {
    @InjectSpy
    private lateinit var exampleService: ExampleService

    @Nested
    inner class HelloTests {
        @Test
        fun `returns Hello`() {
            When { get("/hello") } Then { body(`is`("Hello")) }
        }

        @Test
        fun `returns Bonjour`() {
            doReturn("Bonjour").whenever(exampleService).hello()
            When { get("/hello") } Then { body(`is`("Bonjour")) }
        }
    }

    @Test
    fun `returns Hola`() {
        doReturn("Hola").whenever(exampleService).hello()
        When { get("/hello") } Then { body(`is`("Hola")) }
    }
}

When running the tests repeatedly, the Bonjour test is sometimes red, sometimes green. The others stay green.

Output of uname -a or ver

Darwin *** 21.6.0 Darwin Kernel Version 21.6.0: Mon Dec 19 20:44:01 PST 2022; root:xnu-8020.240.18~2/RELEASE_X86_64 x86_64

Output of java -version

openjdk version "17.0.5" 2022-10-18 OpenJDK Runtime Environment GraalVM CE 22.3.0 (build 17.0.5+8-jvmci-22.3-b08) OpenJDK 64-Bit Server VM GraalVM CE 22.3.0 (build 17.0.5+8-jvmci-22.3-b08, mixed mode, sharing)

GraalVM version (if different from Java)

No response

Quarkus version or git rev

2.13.7.Final-redhat-00003, also tried on 2.16.5.Final

Build tool (ie. output of mvnw --version or gradlew --version)

Apache Maven 3.8.6

Additional information

No response

@lbilger lbilger added the kind/bug Something isn't working label Apr 3, 2023
@quarkus-bot
Copy link

quarkus-bot bot commented Apr 3, 2023

/cc @evanchooly (kotlin), @geoand (kotlin)

@lbilger
Copy link
Author

lbilger commented Apr 3, 2023

This seems to be already solved for @InjectMock. Maybe the same solution can be used for @InjectSpy.

@geoand
Copy link
Contributor

geoand commented Apr 4, 2023

@Sgitario any chance you can take a look?

@Sgitario
Copy link
Contributor

Sgitario commented Apr 4, 2023

InjectMock

I will take a look into this next Tuesday.

@lbilger
Copy link
Author

lbilger commented Apr 5, 2023

A possible workaround is to use QuarkusMock.installMockForInstance in a @BeforeEach method like this:

        @BeforeEach
        fun createRepositorySpy() {
            repositorySpy = spy(ClientProxy.unwrap(repository))
            QuarkusMock.installMockForInstance(repositorySpy, repository)
        }

Sgitario added a commit to Sgitario/quarkus that referenced this issue Apr 13, 2023
The creation of test instances is done recursively, JUnit will call the method `initTestState` for every class. 
So we don't need to call the method `invokeAfterConstructCallbacks` for outer instances.

Fix quarkusio#32383
@quarkus-bot quarkus-bot bot added this to the 3.1 - main milestone Apr 13, 2023
@gsmet gsmet modified the milestones: 3.1 - main, 3.0.1.Final Apr 18, 2023
cescoffier pushed a commit to cescoffier/quarkus that referenced this issue Apr 18, 2023
The creation of test instances is done recursively, JUnit will call the method `initTestState` for every class. 
So we don't need to call the method `invokeAfterConstructCallbacks` for outer instances.

Fix quarkusio#32383
gsmet pushed a commit to gsmet/quarkus that referenced this issue Apr 18, 2023
The creation of test instances is done recursively, JUnit will call the method `initTestState` for every class.
So we don't need to call the method `invokeAfterConstructCallbacks` for outer instances.

Fix quarkusio#32383

(cherry picked from commit 72b1fa1)
@gsmet gsmet modified the milestones: 3.0.1.Final, 2.16.7.Final Apr 18, 2023
gsmet pushed a commit to gsmet/quarkus that referenced this issue Apr 18, 2023
The creation of test instances is done recursively, JUnit will call the method `initTestState` for every class.
So we don't need to call the method `invokeAfterConstructCallbacks` for outer instances.

Fix quarkusio#32383

(cherry picked from commit 72b1fa1)
holly-cummins pushed a commit to holly-cummins/quarkus that referenced this issue Apr 20, 2023
The creation of test instances is done recursively, JUnit will call the method `initTestState` for every class. 
So we don't need to call the method `invokeAfterConstructCallbacks` for outer instances.

Fix quarkusio#32383
benkard pushed a commit to benkard/mulkcms2 that referenced this issue May 11, 2023
This MR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [flow-bin](https://github.com/flowtype/flow-bin) ([changelog](https://github.com/facebook/flow/blob/master/Changelog.md)) | devDependencies | minor | [`^0.203.0` -> `^0.206.0`](https://renovatebot.com/diffs/npm/flow-bin/0.203.1/0.206.0) |
| [org.liquibase.ext:liquibase-hibernate5](https://github.com/liquibase/liquibase-hibernate/wiki) ([source](https://github.com/liquibase/liquibase-hibernate)) | build | minor | `4.20.0` -> `4.21.1` |
| [org.liquibase:liquibase-maven-plugin](http://www.liquibase.org/liquibase-maven-plugin) ([source](https://github.com/liquibase/liquibase)) | build | minor | `4.20.0` -> `4.21.1` |
| [org.jsoup:jsoup](https://jsoup.org/) ([source](https://github.com/jhy/jsoup)) | compile | minor | `1.15.4` -> `1.16.1` |
| [com.vladsch.flexmark:flexmark-all](https://github.com/vsch/flexmark-java) | compile | patch | `0.64.0` -> `0.64.4` |
| [com.diffplug.spotless:spotless-maven-plugin](https://github.com/diffplug/spotless) | build | minor | `2.35.0` -> `2.36.0` |
| [io.quarkus:quarkus-maven-plugin](https://github.com/quarkusio/quarkus) | build | patch | `2.16.6.Final` -> `2.16.7.Final` |
| [io.quarkus:quarkus-universe-bom](https://github.com/quarkusio/quarkus-platform) | import | patch | `2.16.6.Final` -> `2.16.7.Final` |
| [org.apache.maven.plugins:maven-enforcer-plugin](https://maven.apache.org/enforcer/) | build | minor | `3.2.1` -> `3.3.0` |

---

### Release Notes

<details>
<summary>flowtype/flow-bin</summary>

### [`v0.206.0`](flow/flow-bin@f1c1fe9...7bf1c0e)

[Compare Source](flow/flow-bin@f1c1fe9...7bf1c0e)

### [`v0.205.1`](flow/flow-bin@7b34b50...f1c1fe9)

[Compare Source](flow/flow-bin@7b34b50...f1c1fe9)

### [`v0.205.0`](flow/flow-bin@2b838b7...7b34b50)

[Compare Source](flow/flow-bin@2b838b7...7b34b50)

### [`v0.204.1`](flow/flow-bin@283b669...2b838b7)

[Compare Source](flow/flow-bin@283b669...2b838b7)

### [`v0.204.0`](flow/flow-bin@5e0645d...283b669)

[Compare Source](flow/flow-bin@5e0645d...283b669)

</details>

<details>
<summary>liquibase/liquibase-hibernate</summary>

### [`v4.21.1`](https://github.com/liquibase/liquibase-hibernate/releases/tag/v4.21.1)

[Compare Source](liquibase/liquibase-hibernate@v4.21.0...v4.21.1)

Support for Liquibase 4.21.1.

**Full Changelog**: liquibase/liquibase-hibernate@v4.20.0...v4.21.1

### [`v4.21.0`](https://github.com/liquibase/liquibase-hibernate/releases/tag/v4.21.0)

[Compare Source](liquibase/liquibase-hibernate@v4.20.0...v4.21.0)

Support for Liquibase 4.21.0.

#### What's Changed

-   Bump snakeyaml from 1.33 to 2.0 by [@&#8203;dependabot](https://github.com/dependabot) in liquibase/liquibase-hibernate#462
-   Bump spring.version from 6.0.5 to 6.0.6 by [@&#8203;dependabot](https://github.com/dependabot) in liquibase/liquibase-hibernate#464
-   Bump maven-compiler-plugin from 3.10.1 to 3.11.0 by [@&#8203;dependabot](https://github.com/dependabot) in liquibase/liquibase-hibernate#461
-   Fix snyk warning by [@&#8203;filipelautert](https://github.com/filipelautert) in liquibase/liquibase-hibernate#466
-   UniqueConstraintSnapshotGenerator removed to avoid issue of index/constraint recreation by [@&#8203;MalloD12](https://github.com/MalloD12) in liquibase/liquibase-hibernate#468
-   Bump spring.version from 6.0.6 to 6.0.7 by [@&#8203;dependabot](https://github.com/dependabot) in liquibase/liquibase-hibernate#470
-   feat: Make test failing with unique constraints by [@&#8203;fleboulch](https://github.com/fleboulch) in liquibase/liquibase-hibernate#455
-   Bump jacoco-maven-plugin from 0.8.8 to 0.8.9 by [@&#8203;dependabot](https://github.com/dependabot) in liquibase/liquibase-hibernate#473
-   Bump maven-resources-plugin from 3.3.0 to 3.3.1 by [@&#8203;dependabot](https://github.com/dependabot) in liquibase/liquibase-hibernate#471
-   Bump maven-surefire-plugin from 2.22.2 to 3.0.0 by [@&#8203;dependabot](https://github.com/dependabot) in liquibase/liquibase-hibernate#469
-   Fix types handling by [@&#8203;filipelautert](https://github.com/filipelautert) in liquibase/liquibase-hibernate#467

#### New Contributors

-   [@&#8203;MalloD12](https://github.com/MalloD12) made their first contribution in liquibase/liquibase-hibernate#468
-   [@&#8203;fleboulch](https://github.com/fleboulch) made their first contribution in liquibase/liquibase-hibernate#455

**Full Changelog**: liquibase/liquibase-hibernate@v4.19.1...v4.21.0

</details>

<details>
<summary>liquibase/liquibase</summary>

### [`v4.21.1`](https://github.com/liquibase/liquibase/blob/HEAD/changelog.txt#Liquibase-4211-is-a-patch-release)

[Compare Source](liquibase/liquibase@v4.21.0...v4.21.1)

### [`v4.21.0`](https://github.com/liquibase/liquibase/blob/HEAD/changelog.txt#Liquibase-v4210-is-a-major-release)

[Compare Source](liquibase/liquibase@v4.20.0...v4.21.0)

</details>

<details>
<summary>vsch/flexmark-java</summary>

### [`v0.64.4`](vsch/flexmark-java@0.64.2...0.64.4)

[Compare Source](vsch/flexmark-java@0.64.2...0.64.4)

### [`v0.64.2`](vsch/flexmark-java@0.64.0...0.64.2)

[Compare Source](vsch/flexmark-java@0.64.0...0.64.2)

</details>

<details>
<summary>diffplug/spotless</summary>

### [`v2.36.0`](https://github.com/diffplug/spotless/blob/HEAD/CHANGES.md#&#8203;2360---2023-02-27)

##### Added

-   `gradlew equoIde` opens a repeatable clean Spotless dev environment. ([#&#8203;1523](diffplug/spotless#1523))
-   `cleanthat` added `includeDraft` option, to include draft mutators from composite mutators. ([#&#8203;1574](diffplug/spotless#1574))
-   `npm`-based formatters now support caching of `node_modules` directory ([#&#8203;1590](diffplug/spotless#1590))

##### Fixed

-   `JacksonJsonFormatterFunc` handles json files with an Array as root. ([#&#8203;1585](diffplug/spotless#1585))

##### Changes

-   Bump default `cleanthat` version to latest `2.1` -> `2.6` ([#&#8203;1569](diffplug/spotless#1569) and [#&#8203;1574](diffplug/spotless#1574))
-   Reduce logging-noise created by `npm`-based formatters ([#&#8203;1590](diffplug/spotless#1590) fixes [#&#8203;1582](diffplug/spotless#1582))

</details>

<details>
<summary>quarkusio/quarkus</summary>

### [`v2.16.7.Final`](https://github.com/quarkusio/quarkus/releases/tag/2.16.7.Final)

[Compare Source](quarkusio/quarkus@2.16.6.Final...2.16.7.Final)

##### Complete changelog

-   [#&#8203;33023](quarkusio/quarkus#33023) - Fix algorithm comparison bug in OIDC code loading the token decryption key
-   [#&#8203;33020](quarkusio/quarkus#33020) - Fixed example in command-mode-reference.adoc
-   [#&#8203;33012](quarkusio/quarkus#33012) - Update JReleaser guide for native executables
-   [#&#8203;32842](quarkusio/quarkus#32842) - Correct a typo in redis-reference.adoc
-   [#&#8203;32841](quarkusio/quarkus#32841) - Add a column before a table column separator `|`
-   [#&#8203;32838](quarkusio/quarkus#32838) - Fix a typo in security-openid-connect-multitenancy.adoc
-   [#&#8203;32771](quarkusio/quarkus#32771) - Prevent NPE for UserInfo String and Boolean properties
-   [#&#8203;32762](quarkusio/quarkus#32762) - Normalize paths for POM Model providers
-   [#&#8203;32753](quarkusio/quarkus#32753) - Update codestarts to use openjdk container images 1.15
-   [#&#8203;32751](quarkusio/quarkus#32751) - Codestarts - OpenJDK-Container Image not updated
-   [#&#8203;32740](quarkusio/quarkus#32740) - Add missing static import in config interceptor doc
-   [#&#8203;32738](quarkusio/quarkus#32738) - Fix guide oidc trust-store config parameter name
-   [#&#8203;32703](quarkusio/quarkus#32703) - Include MariaDB deprecated.properties
-   [#&#8203;32702](quarkusio/quarkus#32702) - Native MariaDb with useSsl throw NPE
-   [#&#8203;32692](quarkusio/quarkus#32692) - Allow ConfigMappings with default visibility
-   [#&#8203;32690](quarkusio/quarkus#32690) - Quarkus dev mode is not working with a certain type of folder tree due to dependency injection
-   [#&#8203;32679](quarkusio/quarkus#32679) - Logging with Panache: fix LocalVariablesSorter usage
-   [#&#8203;32669](quarkusio/quarkus#32669) - Replace remaining references to bcX-jdk150
-   [#&#8203;32663](quarkusio/quarkus#32663) - infov impacts local variable type
-   [#&#8203;32655](quarkusio/quarkus#32655) - Correct a minor error in native-reference.adoc
-   [#&#8203;32636](quarkusio/quarkus#32636) - Remove reference Uni::then in Mutiny primer
-   [#&#8203;32635](quarkusio/quarkus#32635) - Quarkus Mutiny guide mistake
-   [#&#8203;32603](quarkusio/quarkus#32603) - Avoid calling after construct callbacks twice when using `@Nested` tests
-   [#&#8203;32514](quarkusio/quarkus#32514) - Bump OWASP dependency check plugin version to 8.2.1
-   [#&#8203;32505](quarkusio/quarkus#32505) - Throw the exception if OIDC client fails to acquire the token
-   [#&#8203;32501](quarkusio/quarkus#32501) - Remove unnecessary line split from metadata yaml
-   [#&#8203;32500](quarkusio/quarkus#32500) - `YamlMetadataGenerator` emits yaml with line splits
-   [#&#8203;32481](quarkusio/quarkus#32481) - Fix NPE when OIDC TenantConfigResolver returns null
-   [#&#8203;32480](quarkusio/quarkus#32480) - RestClient with Oidc Token (OidcClientRequestReactiveFilter) is NOT failing when Token is wrong/unauthorized
-   [#&#8203;32449](quarkusio/quarkus#32449) - Multitenancy OIDC permit tenant enumeration
-   [#&#8203;32442](quarkusio/quarkus#32442) - Add one more CORS same origin unit test
-   [#&#8203;32419](quarkusio/quarkus#32419) - Correcting Resteasy Reactive docs
-   [#&#8203;32403](quarkusio/quarkus#32403) - Make SDKMAN releases minor for maintenance and preview releases
-   [#&#8203;32383](quarkusio/quarkus#32383) - Using `@InjectSpy` from a JUnit5 `@Nested` inner class leads to unreliable test result
-   [#&#8203;32360](quarkusio/quarkus#32360) - Qute validation - fix the way the namespace expressions are collected
-   [#&#8203;32355](quarkusio/quarkus#32355) - Cannot using 2 classes with Qute `@MessageBundle` with different namespace
-   [#&#8203;32349](quarkusio/quarkus#32349) - Better error on unparseable GraphQL JSON request
-   [#&#8203;31939](quarkusio/quarkus#31939) - A bit of javadoc for codegen
-   [#&#8203;31581](quarkusio/quarkus#31581) - Arc - Do not validate static members in inner non-static classes for CDI annotations
-   [#&#8203;31558](quarkusio/quarkus#31558) - JUnit `@Nested` Inner Classes with `@BeforeAll` and `@Transactional` annotations fail on initialization after upgrading to 2.16.3.Final
-   [#&#8203;31554](quarkusio/quarkus#31554) - RunTimeMappingsConfigBuilder failures (native build/tests) with 2.16.4

</details>

<details>
<summary>quarkusio/quarkus-platform</summary>

### [`v2.16.7.Final`](quarkusio/quarkus-platform@2.16.6.Final...2.16.7.Final)

[Compare Source](quarkusio/quarkus-platform@2.16.6.Final...2.16.7.Final)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever MR is behind base branch, or you tick the rebase/retry checkbox.

👻 **Immortal**: This MR will be recreated if closed unmerged. Get [config help](https://github.com/renovatebot/renovate/discussions) if that's undesired.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box

---

This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNC4yNC4wIiwidXBkYXRlZEluVmVyIjoiMzQuMjQuMCJ9-->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants