繁体   English   中英

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

[英]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 ,则需要两个步骤:

  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调用放置在构造函数内部,而是放置在其他位置。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM