简体   繁体   English

抽象类受保护的方法junit测试用例

[英]abstract class protected method junit test case

Consider the code: 考虑代码:

abstract public class TigerFinderPage extends TigerPage
private Manager manager;
protected Manager getTiger()
{
    //  If we haven't already done so,  get the tiger.
    if (tiger== null) {
        try {
            tiger= EntityResolution.getTigerFromName(ResTools.resolveNoTranslation(getConfigBundle(), "tiger", ""));
        } catch (Exception e) {
            LogTools.error(logger, null, e);
            return null;
        }
    }
    return tiger;
}

TRY 1: 尝试1:

public class TigerFinderPageTest {

private TigerFinderPage tigerFinderPage;

@Before
public void setUp() throws Exception {

    TigerFinderPage = new TigerFinderPage () {
        @Override
        protected ResourceProvider getBundle() {
            return null;
        }

        @Override
        protected ResourceProvider getConfigBundle() {
            return null;
        }
    };
}

@Test
public void testTigerManager(){
    assertNull(tigerFinderPage.getTiger());
}
}

How Do I test the protected method when they are in different package? 当处于不同包装中的受保护方法时,如何测试? I have tried using reflection, but dont know how to implement it in this case. 我尝试使用反射,但是在这种情况下不知道如何实现。

Testing non-public members ties your tests to your implementation and makes it harder to refactor. 测试非公共成员会将您的测试与您的实现联系起来,并使重构变得更加困难。

If it's significant enough that it can't be tested via the public interface then it must be separate functionality that could live in its own class à la Single Responsibility Principle 如果它的重要性足以不能通过公共接口进行测试,则它必须是可以在其自己的类“ 单一责任原则”中使用的单独功能

In this case I'd have a separate class and tests for LazyTigerFactory : 在这种情况下,我将有一个单独的类和LazyTigerFactory测试:

public final class LazyTigerFactory {
    private Manager manager;
    public Manager getTiger()
    {
        //  If we haven't already done so,  get the tiger.
        if (tiger == null) {
            try {
                tiger= EntityResolution.getTigerFromName(ResTools.resolveNoTranslation(getConfigBundle(), "tiger", ""));
            } catch (Exception e) {
                LogTools.error(logger, null, e);
                return null;
            }
        }
        return tiger;
    }
}

Then use it in your class: 然后在课堂上使用它:

abstract public class TigerFinderPage extends TigerPage
    private final LazyTigerFactory tigerFactory = new LazyTigerFactory();
    protected Manager getTiger(){
       return tigerFactory.getTiger();
    }

Benefits 优点

  • You can get full test coverage around the creation from the factory tests without cluttering your TigerFinderPage tests. 您可以从工厂测试获得关于创建的完整测试覆盖,而不TigerFinderPage测试混乱。
  • You're free to easily change the LazyTigerFactory for another later. 您可以随时轻松地将LazyTigerFactory更改为另一个。
  • TigerFinderPage has fewer direct dependencies. TigerFinderPage具有更少的直接依赖关系。
  • TigerFinderPage is smaller, less Lazy/Entity boiler plate cluttering what this class really does (its single responsibility). TigerFinderPage较小,而懒惰/实体TigerFinderPage则较少此类的实际混乱(它的单一职责)。
  • You can even change to inject a factory interface completely decoupling it which may aid other tests. 您甚至可以进行更改以注入完全解耦的工厂界面,这可能有助于其他测试。

One answer would be to follow JUnit's best practices and have both the production code and the code to test it in the same package , in order to allow accessing protected members, but in different source folders , so the non-production code doesn't disturb the production code. 一种答案是遵循JUnit的最佳实践,并在同一程序包中同时包含生产代码和测试代码,以允许访问protected成员,但在不同的源文件夹中 ,因此非生产代码不会打扰生产代码。 Eg, in maven's structure: 例如,在Maven的结构中:

-- src
   +-- main
       +-- java
           +-- org
               +-- mypackage # Production code for org.mypackage
   +-- test
       +-- java
           +-- org
               +-- mypackage # Testing code for org.mypackage

If this is not an option, you can inherit from the abstract class and increase the visibility of the said method, just so the test can access it: 如果这不是一个选项,则可以从抽象类继承并增加所述方法的可见性,以便测试可以访问它:

public class TigerFinderPageTest {        
    public static class TigerFinderPageDummy extends TigerFinderPage {
        @Override
        protected ResourceProvider getBundle() {
            return null;
        }

        @Override
        protected ResourceProvider getConfigBundle() {
            return null;
        }

        /** Note this method is PUBLIC */
        @Override
        public Manager getTiger() {
            return super.getTiger();
        }
    }

    private TigerFinderPageDummy tigerFinderPage;

    @Before
    public void setUp() throws Exception {
        tigerFinderPage = new TigerFinderPageDummy();
    }

    @Test
    public void testTigerManager(){
        assertNull(tigerFinderPage.getTiger());
    }
}

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

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