具有私有静态非最终字段的

package sample;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class App {
   private static Logger logger = LoggerFactory.getLogger(App.class);

   public void doSomething() {
      logger.error("Cannot do something");
   }
}

try 通过反射设置此字段

package sample;

import org.apache.logging.log4j.core.Logger;
import org.junit.jupiter.api.Test;
import org.springframework.test.util.ReflectionTestUtils;

import static org.mockito.Mockito.mock;

public class AppTest {

    @Test
    public void doSomething() throws Exception {
        App app = new App();

        Logger mockedLogger = mock(Logger.class);

        ReflectionTestUtils.setField(App.class, "logger", mockedLogger);
    }
}

导致非法ArgumentException

Can not set static org.slf4j.Logger field sample.App.logger to org.apache.logging.log4j.core.Logger$MockitoMock$1185285221
java.lang.IllegalArgumentException: Can not set static org.slf4j.Logger field sample.App.logger to org.apache.logging.log4j.core.Logger$MockitoMock$1185285221
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
    at sun.reflect.UnsafeStaticObjectFieldAccessorImpl.set(UnsafeStaticObjectFieldAccessorImpl.java:79)
    at java.lang.reflect.Field.set(Field.java:764)
    at org.springframework.util.ReflectionUtils.setField(ReflectionUtils.java:633)

根据被调用方法的JavaDocs

https://docs.spring.io/spring-framework/docs/5.2.20.RELEASE/javadoc-api/

在提供的Target Class上设置具有给定名称的静态字段 设置为提供的值.

支持设置静态字段.

推荐答案

由于根据堆栈跟踪,IlLegalArgumentException是由java.lang.reflect.Field.set抛出的,因此可以咨询javadoc for Field.set以了解原因.

它写道:

如果指定的对象不是声明基础字段(或其子类或实现者)的类或接口的实例,或者如果展开转换失败,则抛出.

比较您提供的App和AppTest类会发现,AppTest导入org.apache.logging.log4j.core.Logger个,而App导入org.slf4j.Logger

由于您正在try 注入记录器的模拟,因此请将AppTest中的第一个导入更改为org.slf4j.logger.

Java相关问答推荐

Java SSLocket查明客户端是否发送了证书

具有默认分支的JUnit代码覆盖率切换声明

在Java中将Charsequence数组更改为String数组或List String<>

Spring Batch 5-不要让它在数据库中自动创建表

多个Java线程和TreeMap.put()的非预期行为

使用java访问具体子类特定方法的最佳方法是什么?

如何在带有Micronaut的YAML中使用包含特殊字符的字符串作为键

SpringBootreact 式Web应用程序的Spring Cloud Configer服务器中的资源控制器损坏

如何找到MongoDB文档并进行本地化?

试着做一个2x2的魔方求解算法,我如何找到解路径(DFS)?

无法使用Java&;TestContainers获取AWS SQS队列的属性

Java连接池无法正常工作

在添加AdMob时无法为Google Play构建应用程序包:JVM垃圾收集器崩溃和JVM内存耗尽

由于在生成器模式中使用泛型,lambda表达式中的返回类型错误

Lombok@Nonnull是否也对供应商有影响?

一对多关系和ID生成

在使用具有不同成本的谓词调用allMatch之前对Java流进行排序会带来什么好处吗?

持续时间--为什么在秒为负数的情况下还要做额外的工作?

JavaFX:为什么我的ComboBox添加了一个不必要的单元格的一部分?

在数组中查找素数时出现逻辑错误