Skip to content

@MockBean does not work with request-scoped Supplier<T> without explicit name #30043

Open
@mwisnicki

Description

@mwisnicki

Trying to define mock for request-scoped supplier does not work unless I explicitly name the mock.

The problem with hardcoding bean name is that name can be dependent on configuration (for example via use conditions).

If there is no RequestScope or I use custom interface there is no such problem.

Spring Boot 2.7.8 + JDK17

Simplified program:

package com.example.testspringoverridebeantest;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;
import org.springframework.web.context.annotation.RequestScope;

import java.util.function.Supplier;

@SpringBootApplication
public class TestSpringOverrideBeanTestApplication {

    @Bean
    @RequestScope
    Supplier<String> word() {
        return () -> "app";
    }

    @Bean
    @RequestScope
    @Profile("test") // just an example condition
    @Primary
    Supplier<String> testWord() {
        return () -> "testapp";
    }

    public static void main(String[] args) {
        SpringApplication.run(TestSpringOverrideBeanTestApplication.class, args);
    }

}

@Service
record Greeter(Supplier<String> word) {
    String hello() {
        return "hello, " + word.get();
    }
}
package com.example.testspringoverridebeantest;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;

import java.util.function.Supplier;

@SpringBootTest
class TestSpringOverrideBeanTestApplicationTests {

    @Autowired
    Greeter greeter;

    @MockBean// (name = "testWord") // unbreaks but the name can vary!
    Supplier<String> word;

    @Test
    void canOverrideBeanForTest() {
        Mockito.when(word.get()).thenReturn("test");
        Assertions.assertEquals("hello, test", greeter.hello());
    }

}

Metadata

Metadata

Assignees

No one assigned

    Labels

    in: coreIssues in core modules (aop, beans, core, context, expression)type: bugA general bug

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions