[英]How to mock a protected variable in an abstract class
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”或类似名称,这样更清晰,但已经有了一个答案,并且会再次破坏它。对于这个不好的问题,我宁愿在实时聊天中进行讨论,但我无法访问它。
如果要在构造函数中使用模拟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);
}
}
最后,尽管这显然是基于意见的,并且取决于用例,但有人可能会争辩说 :构造函数不是记录器,因此它应仅构造一个对象,而不打印日志消息。 因此,您可以考虑不将logger
调用放置在构造函数内部,而是放置在其他位置。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.