From 9940fcfe77469975bfb621b1882464fcd8f421f8 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 1 Feb 2023 17:22:36 +0000 Subject: [PATCH] Reset mocks produced by FactoryBeans MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit An unwanted side-effect of the changes made in c6bdd136 to fix gh-7271 is that a mock produced by a factory bean is not reset. To allow such a mock to be reset without regressing the fix we now call getBean(…) as we did before c6bdd136, however the call is now performed in a defensive manner falling back to getSingleton(…) when it fails. Closes gh-33830 --- .../ResetMocksTestExecutionListener.java | 13 +++++++-- .../ResetMocksTestExecutionListenerTests.java | 28 ++++++++++++++++++- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/ResetMocksTestExecutionListener.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/ResetMocksTestExecutionListener.java index 2033c2e648f..d3157918e09 100644 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/ResetMocksTestExecutionListener.java +++ b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/ResetMocksTestExecutionListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -78,7 +78,7 @@ public class ResetMocksTestExecutionListener extends AbstractTestExecutionListen for (String name : names) { BeanDefinition definition = beanFactory.getBeanDefinition(name); if (definition.isSingleton() && instantiatedSingletons.contains(name)) { - Object bean = beanFactory.getSingleton(name); + Object bean = getBean(beanFactory, name); if (reset.equals(MockReset.get(bean))) { Mockito.reset(bean); } @@ -100,4 +100,13 @@ public class ResetMocksTestExecutionListener extends AbstractTestExecutionListen } } + private Object getBean(ConfigurableListableBeanFactory beanFactory, String name) { + try { + return beanFactory.getBean(name); + } + catch (Exception ex) { + return beanFactory.getSingleton(name); + } + } + } diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/ResetMocksTestExecutionListenerTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/ResetMocksTestExecutionListenerTests.java index a90256d1385..1c51cedf944 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/ResetMocksTestExecutionListenerTests.java +++ b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/ResetMocksTestExecutionListenerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -52,6 +52,7 @@ class ResetMocksTestExecutionListenerTests { given(getMock("none").greeting()).willReturn("none"); given(getMock("before").greeting()).willReturn("before"); given(getMock("after").greeting()).willReturn("after"); + given(getMock("fromFactoryBean").greeting()).willReturn("fromFactoryBean"); } @Test @@ -59,6 +60,7 @@ class ResetMocksTestExecutionListenerTests { assertThat(getMock("none").greeting()).isEqualTo("none"); assertThat(getMock("before").greeting()).isNull(); assertThat(getMock("after").greeting()).isNull(); + assertThat(getMock("fromFactoryBean").greeting()).isNull(); } ExampleService getMock(String name) { @@ -102,6 +104,11 @@ class ResetMocksTestExecutionListenerTests { return new BrokenFactoryBean(); } + @Bean + WorkingFactoryBean fromFactoryBean() { + return new WorkingFactoryBean(); + } + } static class BrokenFactoryBean implements FactoryBean { @@ -123,4 +130,23 @@ class ResetMocksTestExecutionListenerTests { } + static class WorkingFactoryBean implements FactoryBean { + + @Override + public ExampleService getObject() { + return mock(ExampleService.class, MockReset.before()); + } + + @Override + public Class getObjectType() { + return ExampleService.class; + } + + @Override + public boolean isSingleton() { + return true; + } + + } + }