当前位置: 首页 > 知识库问答 >
问题:

@mockbean-在方法注入之前通过@autowire使用的实例

应和光
2023-03-14

在我的JUNIT5-test中,我想通过@mockbean模拟一个bean。在my@beforeech-method中,调用被注入。但是其他bean@autowire-ing@mockbean在方法注入之前用@mockbean实例化。这很奇怪,给了我NPES。在使用@mockbean之前,我如何强制方法注入?

@SpringBootTest
@ExtendWith(SpringExtension.class)
@ContextConfiguration("classpath:context/authenticationStaff.xml")
@EnableAutoConfiguration
public class PasswordPolicyServiceTest {

    private final List<Reference> bcryptDigestRefs = new ArrayList<>();
    private final DigestHistoryRule bcryptDigestRule = new DigestHistoryRule(new BCryptHashBean());
    @MockBean
    private SystemConfiguration systemConfiguration; 

    @BeforeEach
    public void initMock() {
        MockitoAnnotations.initMocks(this);
        Arrays.asList(SystemConfigKey.values()).forEach(key -> {
            Mockito.when(systemConfiguration.getConfig(key)).thenReturn(getConfig(key, key.getDefaultValue()));
        });
        Mockito.when(systemConfiguration.getConfig(SystemConfigKey.MIN_PASSWORD_LENGTH)).thenReturn(getConfig(SystemConfigKey.MIN_PASSWORD_LENGTH, "5"));

不及格的班级是:

@Service
public class SessionCacheManager {


    private final Ehcache ehCache;

    private final Cache<String, SessionVerificationType> sessionCache;

    private final SystemConfiguration systemConfiguration;

    @Autowired
    public SessionCacheManager(final Ehcache ehCache, final SystemConfiguration systemConfiguration) {
        this.ehCache=ehCache;
        this.systemConfiguration=systemConfiguration;
        SystemConfigType systemConfig = systemConfiguration.getConfig(SystemConfigKey.SESSION_MAX_NUMBER);
        Integer numberOfParalledSessions = systemConfig.getIntegerValue();
        CacheManager cacheManager=ehCache.registerNewCacheManager(CACHE_MANAGER);
        sessionCache = cacheManager.createCache(CACHE_NAME, 
                CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class, SessionVerificationType.class, ResourcePoolsBuilder.heap(numberOfParalledSessions)));
    }

正如我所看到的(使用调试),“SessionCacheManager”使用模拟的“SystemConfiguration”但是SystemConfiguration.getConfig(SystemConfigKey.session_max_number);返回空值。

共有1个答案

龙华翰
2023-03-14

我帮助了自己,尽管我不喜欢我的解决方案。与其说是解决办法,不如说是一种把戏。但我现在想不出别的了。

我将@ContextConfiguration更改为:

@ContextConfiguration(locations = "/context/authenticationStaff.xml", classes = { SpringApplicationContext.class })

XML被设置为不能自动检测类“SystemConfiguration.class”。与此相反,“SpringApplicationContext.class”将“SystemConfiguration.class”作为模拟bean提供。

@Configuration
public class SpringApplicationContext {

    @Mock
    private SystemConfiguration mockedSystemConfiguration;

    @Bean
    public SystemConfiguration systemConfiguration() {
        MockitoAnnotations.initMocks(this);
        Arrays.asList(SystemConfigKey.values()).forEach(key -> {
            Mockito.when(mockedSystemConfiguration.getConfig(key)).thenReturn(getConfig(key, key.getDefaultValue()));
        });
        Mockito.when(mockedSystemConfiguration.getConfig(SystemConfigKey.MIN_PASSWORD_LENGTH)).thenReturn(getConfig(SystemConfigKey.MIN_PASSWORD_LENGTH, "5"));
        Mockito.when(mockedSystemConfiguration.getConfig(SystemConfigKey.PASSWORD_BCRYPTENCODER_COSTFACTOR)).thenReturn(getConfig(SystemConfigKey.PASSWORD_BCRYPTENCODER_COSTFACTOR, "5"));
        return mockedSystemConfiguration;
    }

    private SystemConfigType getConfig(SystemConfigKey key, String value) {
        SystemConfigType config = new SystemConfigType();
        config.setKey(key);
        config.setValue(value); 
        return config;
    }

测试代码现在如下所示:

@SpringBootTest
@ExtendWith(SpringExtension.class)
@ContextConfiguration(locations = "/context/authenticationStaff.xml", classes = { SpringApplicationContext.class })
@EnableAutoConfiguration
public class PasswordPolicyServiceTest {

    @Autowired 
    private PasswordPolicyService passwordPolicyService;
    @Autowired 
    private PasswordHandlerService passwordHandlerService;
    @Autowired
    private SystemConfiguration systemConfiguration;

    private final List<Reference> bcryptDigestRefs = new ArrayList<>();

    private final DigestHistoryRule bcryptDigestRule = new DigestHistoryRule(new BCryptHashBean());

    @BeforeEach
    public void initMock() {
        MockitoAnnotations.initMocks(this);
        String password=passwordHandlerService.getPassword("my$Password");
        bcryptDigestRefs.add(
                new HistoricalReference(
                        "bcrypt-history",
                        password));
    }

这很有效,但不是一个好的解决方案。非常欢迎其他建议。

 类似资料:
  • 我找到了一些答案:https://stackoverflow.com/a/21218921/2754014 关于依赖注入。没有任何注释,如,或。让我们假设此示例没有任何 XML 配置 的 bean (除了简单

  • 本文向大家介绍spring中通过ApplicationContext getBean获取注入对象的方法实例,包括了spring中通过ApplicationContext getBean获取注入对象的方法实例的使用技巧和注意事项,需要的朋友参考一下 用SpringContextUtil实现ApplicationContextAware 工具类 在Spring的配置文件中配置这个类,Spring容器会

  • 问题内容: 我不确定使用Spring3将Hibernate的会话实例注入DAO类的最佳方法是什么。我没有为此使用Spring的Hibernate Template支持,所以这是我在DAO类中拥有的代码。 下面是将会话注入此方法的代码 我不确定这是否是进行SessionFactory注入的最佳方法,因为我们不想在项目中使用Spring模板。因此,任何其他改进建议都将很有帮助。 问题答案: 在Spri

  • 本文向大家介绍Spring中@Autowire注入的深入讲解,包括了Spring中@Autowire注入的深入讲解的使用技巧和注意事项,需要的朋友参考一下 一直在思考spring的@Autowire注入属性时到底是按类型注入还是按名称注入,今天写了一个测试来证明一下。 定义接口TestService 定义接口实现:TestServiceImpl1和TestServiceImpl2 定义一个bean

  • 另外,请举例说明何时使用annotaion。 提前感谢。

  • 我想编写控制器测试,也测试我的注释。到目前为止,我所读到的是,这是一条出路。 当我只有一个控制器可以顺利工作时。然而,当有两个或更多控制器测试类时,@mockbean似乎没有被正确使用。根据测试执行顺序,第一个测试类中的所有测试都会成功,而其他所有测试都会失败。 在下面的测试运行中,首先执行PotatoControllerTest,然后执行FooControllerTest。 我试图用一个通用的来