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

Spring Test support for @MockBean or similar [SPR-14083] #18655

Closed
spring-projects-issues opened this issue Mar 23, 2016 · 11 comments
Closed

Spring Test support for @MockBean or similar [SPR-14083] #18655

spring-projects-issues opened this issue Mar 23, 2016 · 11 comments
Labels
in: core Issues in core modules (aop, beans, core, context, expression) in: test Issues in the test module status: superseded An issue that has been superseded by another type: enhancement A general enhancement

Comments

@spring-projects-issues
Copy link
Collaborator

Martin Meyer opened SPR-14083 and commented

If I have a Transaction Manager running in unit tests, it becomes impossible for Mockito to properly initialize and inject mocks. This problem seems to be related to usage of proxy classes, not specific to using a transaction manager.

Here's a basic example of a test class:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {EnableTransactionManager.class})
public class SomeTest {
    @Mock
    private MockBean someMockedBean;

    @Autowired
    @InjectMocks
    private RealBean someRealBean;

    @Before
    public void before() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void someTest() {
        someRealBean.doSomething();
    }
}

What I see in the debugger is that on the someRealBean.doSomething() line, someRealBean contains a mock reference to my MockBean instance. But when I set the next breakpoint within RealBean#doSomething() and go there, the local field within the object is not a mock one, it's a real @Autowire'd bean.

In real terms, the impact on me is that tests fail whenever I try to implement a TransactionManager and have it configured during tests. I end up trying to call DAO methods that should have been mocked, and it tries to issue database calls on a DataSource that isn't really ready to service them.

I think the problem is a race between Mockito and Spring to performing their setup. I think the solution is for SpringJUnit4ClassRunner to automagically call the equivalent of MockitoAnnotations.initMocks(this) if org.mockito.Mockito is in the classpath. This would mean adding an optional dependency on Mockito.

There was an issue opened against Mockito for this, which was closed as WONTFIX. They suggested that it be fixed in Spring instead of bringing in a Spring dependency there.

The obvious workaround here is to not enable anything that will do AOP proxying during your unit tests.


Affects: 4.2.5

@spring-projects-issues
Copy link
Collaborator Author

Michael Huffman commented

I do not believe this is a Spring issue. Mockito's PropertyAndSetterInjection appears to have a design flaw/limitation in that it uses field declaration of a class as a means to determine candidate injection types and properties. When a proxy is used, particularly a CGLIB proxy, the fields have no correlation to the public properties (setters) available for use in injection. Therefore, the injection filtering does not find the properties/setters suitable to inject. I have reported a comment on your original bug report in Mockito.

@spring-projects-issues
Copy link
Collaborator Author

Martin Meyer commented

Has anyone looked back at this problem in the past two years? This problem persists and from a user perspective it really seems like I shouldn't have to go so far out of my way to inject mocks. Mockito has been under much heavier development lately, and with all that's changed in JUnit 5 and Spring Framework 5 maybe fixing this problem might be easier than it was when I originally filed the issue..?

@spring-projects-issues spring-projects-issues added status: waiting-for-triage An issue we've not yet triaged or decided on in: test Issues in the test module type: enhancement A general enhancement in: core Issues in core modules (aop, beans, core, context, expression) and removed type: enhancement A general enhancement labels Jan 11, 2019
@rstoyanchev rstoyanchev added status: bulk-closed An outdated, unresolved issue that's closed in bulk as part of a cleaning process and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Jan 11, 2019
@spring-projects-issues
Copy link
Collaborator Author

Bulk closing outdated, unresolved issues. Please, reopen if still relevant.

@elreydetodo
Copy link

This is definitely still relevant. It has tripped up other developers on almost every project I've worked on involving Spring Framework. We always get into a state early on where unit tests aren't passing and we can't figure out why, and it always turns out it's because injecting mocks on something being proxied by cglib doesn't work as expected. Once we re-realize the problem, we start using ReflectionTestUtils to set the field, but then everyone forgets why we're doing it in some tests and not others, and we run amok using ReflectionTestUtils almost everywhere instead of @InjectMocks.

We really could use a better system to do this for us. This shouldn't be so hard and manual. Even discovering that this is a problem isn't that easy.

@rstoyanchev rstoyanchev reopened this Jan 21, 2019
@rstoyanchev rstoyanchev added status: waiting-for-triage An issue we've not yet triaged or decided on for: team-attention and removed status: bulk-closed An outdated, unresolved issue that's closed in bulk as part of a cleaning process labels Jan 21, 2019
@philwebb
Copy link
Member

@elreydetodo Have you seen the @MockBean annotation from Spring Boot?

@philwebb
Copy link
Member

A similar proxy issue was raised in Spring Boot spring-projects/spring-boot#6871 with @MockBean

@philwebb philwebb added status: waiting-for-feedback We need additional information before we can continue and removed for: team-attention labels Feb 11, 2019
@spring-projects-issues
Copy link
Collaborator Author

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

@spring-projects-issues spring-projects-issues added the status: feedback-reminder We've sent a reminder that we need additional information before we can continue label Feb 18, 2019
@elreydetodo
Copy link

Actually it looks like that would resolve the problem. I'm reading a little into that issue and the Javadoc of MockBean and MockitoTestExecutionListener, and it sounds like this thing is what I want, except for some reason it's done in Spring Boot instead of as part of the core framework.

Can we get that annotation and the test execution listener promoted to spring-test?

@elreydetodo
Copy link

Please note that I'm not using Spring Boot, so I can't simply use that annotation and be done with it. Spring Boot doesn't seem like the appropriate place for such fundamental functionality to live.

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue status: feedback-reminder We've sent a reminder that we need additional information before we can continue labels Feb 20, 2019
@greylurk
Copy link

It's been about a year since it was suggested to move the MockBean annotation (and its affiliated functionality) from the spring-boot project to the spring-test project. What's involved in completing that move?

@snicoll snicoll changed the title spring-test should handle @Mock [SPR-14083] Spring Test support for @MockBean or similar [SPR-14083] Sep 20, 2023
@jhoeller jhoeller added type: enhancement A general enhancement and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Dec 29, 2023
@jhoeller jhoeller added this to the 6.x Backlog milestone Dec 29, 2023
@sbrannen sbrannen changed the title Spring Test support for @MockBean or similar [SPR-14083] Spring Test support for @MockBean or similar [SPR-14083] Mar 10, 2024
@sbrannen
Copy link
Member

Superseded by #29917 which introduces support for @TestBean, @MockitoBean, and @MockitoSpyBean in the spring-test module in Spring Framework 6.2.

@sbrannen sbrannen closed this as not planned Won't fix, can't repro, duplicate, stale Mar 10, 2024
@sbrannen sbrannen removed this from the 6.x Backlog milestone Mar 10, 2024
@sbrannen sbrannen added status: superseded An issue that has been superseded by another and removed status: feedback-provided Feedback has been provided labels Mar 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) in: test Issues in the test module status: superseded An issue that has been superseded by another type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

7 participants