This error is displayed when I use it like this
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'elasticFetchFactory' defined in file [D:\jworkspace\datamapper\datamapper-core\target\classes\com\core\tags\elastic\ElasticFetchFactory.class]: Error setting property values; nested exception is org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessExceptions (3) are:
PropertyAccessException 1: org.springframework.beans.MethodInvocationException: Property 'resolutePaths' threw exception; nested exception is java.lang.NullPointerException
PropertyAccessException 2: org.springframework.beans.MethodInvocationException: Property 'name' threw exception; nested exception is java.lang.NullPointerException
PropertyAccessException 3: org.springframework.beans.MethodInvocationException: Property 'beanName' threw exception; nested exception is java.lang.NullPointerException
the code
@Component
public class A {
private String[] resolutePaths;
private String name;
private String beanName;
public void setResolutePaths(String[] resolutePaths) {
this.resolutePaths = resolutePaths;
}
public void setName(String name) {
this.name = name;
}
public void setBeanName(String name) {
this.beanName = beanName;
}
@Autowired
private B b;
public void aFoo() {
b.bFoo();
}
}
@Component
public class B {
private String[] resolutePaths;
private String name;
private String beanName;
public void setResolutePaths(String[] resolutePaths) {
this.resolutePaths = resolutePaths;
}
public void setName(String name) {
this.name = name;
}
public void setBeanName(String name) {
this.beanName = beanName;
}
@Autowired
private ApplicationContext context;
public void bFoo() {
C bean = context.getBean(C.class);
bean.foo();
}
}
@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class C {
private String[] resolutePaths;
private String name;
private String beanName;
public void setResolutePaths(String[] resolutePaths) {
this.resolutePaths = resolutePaths;
}
public void setName(String name) {
this.name = name;
}
public void setBeanName(String name) {
this.beanName = beanName;
}
public void foo() {
}
}
public class TestBeanDefinitionScanner extends ClassPathBeanDefinitionScanner {
public TestBeanDefinitionScanner(BeanDefinitionRegistry registry) {
super(registry, false);
}
protected void registerFilters() {
addIncludeFilter(new AnnotationTypeFilter(Component.class));
}
@Override
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
return super.doScan(basePackages);
}
}
public class TestRegistry implements ImportBeanDefinitionRegistrar, ResourceLoaderAware {
private ResourceLoader resourceLoader;
@SuppressWarnings("unchecked")
@Override
public void registerBeanDefinitions(AnnotationMetadata unuse,
BeanDefinitionRegistry registry) {
TestBeanDefinitionScanner scanner =
new TestBeanDefinitionScanner(registry);
scanner.setResourceLoader(resourceLoader);
scanner.registerFilters();
Set<BeanDefinitionHolder> holders = scanner.doScan("com.core.test");
for (BeanDefinitionHolder holder : holders) {
BeanDefinition beanDefinition = holder.getBeanDefinition();
ScannedGenericBeanDefinition definition =
(ScannedGenericBeanDefinition) beanDefinition;
MutablePropertyValues values = definition.getPropertyValues();
values.add("resolutePaths", new String[]{});
values.add("name", "test");
values.add("beanName", "testBean");
}
}
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
}
@SpringBootTest
public class Test {
@Autowired
A a;
@Test
void test() {
try (MockedConstruction<C> c = Mockito.mockConstruction(C.class,
withSettings().defaultAnswer(Answers.CALLS_REAL_METHODS))) {
a.aFoo();
verify(c.constructed().get(0), times(1)).foo();
}
}
}
the springboot version is 2.7.3. How can I solve it, or should Mockito handle this problem?
Comment From: cglcl
This is a truncated sample of my code, but my code does get the mock C bug!
Comment From: wilkinsona
Thanks for the report. Unfortunately, it's not clear how the various pieces fit together or why you believe this may be a Spring Boot problem. For example, I can't tell how TestBeanDefinitionScanner
and TestRegistry
are used.
If you would like us to spend some more time investigating, please spend some time providing a complete yet minimal sample that reproduces the problem. You can share it with us by pushing it to a separate repository on GitHub or by zipping it up and attaching it to this issue.
Comment From: cglcl
like this
@SpringBootTest
@Import(TestRegistry.class)
public class Test {
@Autowired
A a;
@Test
void test() {
try (MockedConstruction<C> c = Mockito.mockConstruction(C.class,
withSettings().defaultAnswer(Answers.CALLS_REAL_METHODS))) {
a.aFoo();
verify(c.constructed().get(0), times(1)).foo();
}
}
}
Comment From: cglcl
Maybe This feels like a Spring Framework issue, but more like Mockito's because the classes it mocks cannot set properties in spring. I'm looking for some help. Is there any way I can verify the number of calls to a method on a prototype bean in the spring container?
Comment From: cglcl
When I debug it, I got this is not available
error!
Comment From: wilkinsona
If you are looking for help and guidance, please ask on Stack Overflow as requested in our guidelines for contributing. Before you do that, I would ask yourself if this is worth testing. It feels like you're trying to test the container rather than your own code.
If I've misunderstood and you believe you've found a bug, we can re-open the issue and take another look once you have provided a complete yet minimal sample that we can easily run to reproduce the problem. It should reproduce the problem without modification and without us having to copy-paste snippets of code.
Comment From: cglcl
I just did. It's been bugging me all day. The class Mockito mocks will not call the constructor of the parent class. However, I did some operations in the constructor, causing the mock class to fail without doing these operations.