gpt4 book ai didi

java - 测试阶段@Inject字段

转载 作者:行者123 更新时间:2023-12-01 09:44:40 24 4
gpt4 key购买 nike

我正在向我的应用程序添加日志记录功能,并使用由 log4j 实现的 slf4j。为了简化我的代码,我有一个辅助类来生成记录器(这个想法不是我的,我从 Beginning Java EE 7 by Antonio Goncalves 获取它),该类如下所示:

import javax.enterprise.inject.Produces;
import javax.enterprise.inject.spi.InjectionPoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class LoggerProducer {

@Produces
public Logger createLogger(InjectionPoint injPoint) {
return LoggerFactory.getLogger(injPoint.getMember().getDeclaringClass());
}
}

所以在我的类里面我所要做的(理论上)是:

public class SomeClass {
@Inject private Logger logger; // this could be private or default, doesn't matter
}

问题是在测试阶段我没有启用 CDI,因为我在容器外部运行代码。我无法手动注入(inject),因为我有一些带有自己的记录器的抽象类,因此我无法实例化该类并为其分配一个 Logger 实例。

有没有办法在测试阶段“启用”CDI?我的项目是使用 Maven 构建的,我将部署到 Wildfly 10 服务器。预先感谢您的回答。

注意

我不能做类似的事情

public class SomeClassTest {
private SomeClass someClass; // this is the class I want to test

@Before
public void init() {
someClass.logger = LoggerFactory.getLogger(SomeClass.class);
}

@Test
public void someTest(){...}
}

因为我有一些抽象类,它们有自己的私有(private) Logger logger 属性,我需要保持这种方式(我不能声明它 protected ),因为我想要为了跟踪消息抛出的位置,所以我需要将记录器保持私有(private)。例如。我有类似的东西

public abstract class MyAbstract {
@Inject
private Logger logger;
}

public class MyConcrete extends MyAbstract {
@Inject
private Logger logger;
}

我可以在测试类中将 MyConcrete.logger 设置为默认值,但我无法对 MyAbstract.logger 执行此操作,因为它们位于不同的包中我无法实例化MyAbstract`,我的解释正确吗?

注释2

我的项目结构是这样的:

package common

import org.slf4j.logger
...

public abstract class Generic {
@Inject
private Logger logger;

public void doSomethingGeneric(){
// do something and log it
}
}

package specific

import ...

public class Concrete extends Generic{
@Inject
Logger logger;

// some concrete methods...
}

package specific

public class ConcreteTest {
private Concrete concrete;

@Before
public void init() {
concrete = new Concrete();
concrete.logger = LoggerFactory.getLogger(Concrete.class); // Dependency injection by hand
}

// some @Test methods
}

最终,来自 ConcreteTest@Test 方法调用 Concrete.doSomethingGeneric(),因为它继承到了 concrete 实例。问题是 doSomethingGeneric() 使用 Generic 记录器记录,我不知道如何以干净的方式满足该依赖关系(我不想用生产中不需要设置方法)

最佳答案

您可以使用mockito测试单元来做到这一点:

@RunWith(MockitoJUnitRunner.class)
public class MyBeanTest {

@Spy
private Logger logger = LoggerProducer.getLogger();

@InjectMocks
private MyBean myTestBean; // = new MyBean(parameters). explicit if no default constructir

@Test
public void verifySomeLogic() {
myTestBean.doSomething();
}
}

在这里,mockito运行时和代理将管理注入(inject),您甚至可以对记录器本身进行验证。

关于java - 测试阶段@Inject字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38161459/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com