Skip to content

@MockitoBean reset and MockitoSession management do not work with @Nested tests #33676

Closed
@wilkinsona

Description

@wilkinsona

Affects: 6.2.0-SNAPSHOT

The following reproduces the problem:

package com.example;

import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import static org.mockito.BDDMockito.then;
import static org.mockito.Mockito.times;

@ExtendWith(SpringExtension.class)
class InheritedNestedTestConfigurationTests {

	@MockitoBean(enforceOverride = false)
	Action action;

	@Autowired
	ActionPerformer performer;

	@Test
	void mockWasInvokedOnce() {
		this.performer.run();
		then(this.action).should().perform();
	}

	@Test
	void mockWasInvokedTwice() {
		this.performer.run();
		this.performer.run();
		then(this.action).should(times(2)).perform();
	}

	@Nested
	class InnerTests {

		@Test
		void mockWasInvokedOnce() {
			InheritedNestedTestConfigurationTests.this.performer.run();
			then(InheritedNestedTestConfigurationTests.this.action).should().perform();
		}

		@Test
		void mockWasInvokedTwice() {
			InheritedNestedTestConfigurationTests.this.performer.run();
			InheritedNestedTestConfigurationTests.this.performer.run();
			then(InheritedNestedTestConfigurationTests.this.action).should(times(2)).perform();
		}

	}

	public interface Action {

		void perform();

	}

	static class ActionPerformer {

		private final Action action;

		ActionPerformer(Action action) {
			this.action = action;
		}

		void run() {
			this.action.perform();
		}

	}

	@Configuration(proxyBeanMethods = false)
	static class TestConfiguration {

		@Bean
		ActionPerformer actionPerformer(Action action) {
			return new ActionPerformer(action);
		}

	}

}

One of the two tests in InnerTests will fail because the mock will have been called more times than expected as it has not been reset between the two tests. I think this part of the problem was introduced in 65d2191. With a local fix for that in place, the failure still occurs. Looking in the debugger, this is because there are two instances of the action mock, one that has been injected into the tests and one that's being reset by MockitoResetTestExecutionListener.

Metadata

Metadata

Assignees

Labels

in: testIssues in the test moduletype: bugA general bug

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions