如何在抽象类中模拟受保护的变量



Edit2:我只是瞎了眼,没有看到记录器初始化得像

this.logger = authotrization.getLogger();

像所有其他构造函数一样,我猜过度工作,授权作为参数传递,所以现在很容易,这篇文章现在无关紧要,谢谢大家的时间

编辑:所以我稍微编辑了一下我的问题,所以很清楚我想做什么,希望现在它是堆栈溢出标准,我一直很着急,我很抱歉

以下测试结果为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,我不知道如何让 mock 知道我希望这个记录器什么都不做

我会将"SomeClass"重命名为"SomeAbstractClass"或类似的东西,这样它更清楚,但已经有一个答案,它会再次毁了它对不起这个糟糕的问题我宁愿在实时聊天中讨论它,但我无法访问它。

如果要在构造函数中使用模拟logger,则需要两个步骤:

  1. 在测试代码中创建模拟。
  2. 将其传递给您的生产代码,例如作为构造函数参数。

示例测试可能如下所示:

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调用放在构造函数中,而不是放在其他地方。

最新更新