Edit2:我只是盲目,没有看到记录器的初始化方式
this.logger = authotrization.getLogger();
在构造函数中,和其他所有构造函数一样,我认为过度劳累,将授权作为参数传递,因此现在很容易,本文无关紧要,谢谢大家的宝贵时间
编辑:所以我编辑了我的问题,以便清楚地知道我要做什么,希望现在是在stackoverflow标准中,我很着急,很抱歉。
以下测试结果为NullPointerException
。是否有可能避免这种情况,例如通过嘲笑受保护的logger
?
abstract public class SomeClass {
protected Legs legs;
protected Logger logger;
public SomeClass(String name, Cat cat) {
this.legs = cat.getLegs();
logger.info("Creating new {}", name);
}
}
在类内部有更多的变量,在构造函数内有更多的参数,这些变量正在为变量分配一些值,但它们不会以任何方式影响记录器,因此我没有提及它们。
这是我的测试班简化了:
@RunWith(PowerMockRunner.class)
public class SomeClassTest {
private ClassThatExtendsSomeClass classThatExtends;
@Mock
private Cat cat;
@Mock
private Logger logger;
@Before
public void setUp() {
mock(Cat.class)
doReturn(new Legs()).when(cat).getLegs();
mock(Logger.class)
doNothing().when(logger).info(anyString(), anyObject());
}
@Test
public void test() {
classThatExtends = new ClassThatExtendsSomeClass("Hello World", cat);
//it always fails here on the logger line in SomeClass
}
}
模拟猫是有效的,因为它是作为参数传递的,并且程序知道我要模拟哪只猫,但是对于记录器来说,这并不是因为我无法将其作为参数传递,而且不是@Inject,我也不知道不知道如何让模拟知道我想要这个记录器什么都不做
我会将“ SomeClass”重命名为“ SomeAbstractClass”或类似名称,因此更清晰,但已经有了一个答案,并且会再次破坏它,以解决这个不好的问题,我宁愿在实时聊天中讨论它,但我无法访问它。
答案 0 :(得分:1)
如果要在构造函数中使用模拟的logger
,则需要两个步骤:
样本测试可能如下所示:
import org.junit.Test;
import org.slf4j.Logger;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.mock;
public class SomeClassTest {
@Test
public void shouldNotRequireLogger() {
Logger logger = mock(Logger.class);
String name = "name";
SomeClass someClass = new SomeTestClass(logger, name);
assertNotNull(someClass.logger);
}
public class SomeTestClass extends SomeClass {
SomeTestClass(Logger logger, String name) {
super(logger, name);
}
}
}
避免使用NullPointerException
的另一种可能性是预先初始化记录器。但是,它会以这种方式在测试过程中打印日志(可能会有帮助):
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class SomeClass {
protected static final Logger LOGGER = LoggerFactory.getLogger(SomeClass.class);
public SomeClass(String name) {
LOGGER.info("Creating new {}", name);
}
}
最后,尽管这显然是基于意见的,并且取决于用例,但有人可能会争辩:构造函数不是记录器,因此它只能 construct 对象,而不显示 log 消息。因此,您可以考虑不将logger
调用放在构造函数内部,而应该放在其他地方。