我正在为我的应用添加日志记录功能,而我正在使用slf4j
实现的log4j
。为了简化我的代码,我有一个帮助程序类来生成一个记录器(这个想法不是我的,我是从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,因为我在容器外运行代码。我无法手动注入,因为我有一些带有自己的记录器的抽象类,所以我无法实例化该类并为其分配Logger
实例。
有没有办法在测试阶段“启用”CDI?我的项目是用Maven构建的,我将部署到Wildfly 10 Server。提前感谢您的回答。
我不能做像
这样的事情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(){...}
}
因为我有一些带有自己的私有Logger logger
属性的抽象类,我需要保持这种方式(我不能声明它protected
)因为我想要跟踪一下消息被抛出,所以我需要保持记录器私有。例如。我有类似
public abstract class MyAbstract {
@Inject
private Logger logger;
}
public class MyConcrete extends MyAbstract {
@Inject
private Logger logger;
}
我可以从测试类中将MyConcrete.logger
设置为默认值,但我可以t do that for
MyAbstract.logger because they are in different packages and I can't instantiate
MyAbstract`,我能正确解释吗?
我的项目结构是这样的:
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
}
最终,来自@Test
的{{1}}方法调用ConcreteTest
,因为它继承到Concrete.doSomethingGeneric()
实例。问题是concrete
使用doSomethingGeneric()
记录器进行日志记录,我不知道如何以干净的方式满足该依赖项(我不希望使用生产所不需要的setter方法来破解我的代码)
答案 0 :(得分:1)
您可以使用模拟测试单元执行此操作:
["Marseille", "Marsan", "Martin"].map { |x| x[0,4] }
# => ["Mars", "Mars", "Mart"]
此处,mockito运行时和代理将管理注入,您甚至可以对记录器本身进行验证。