公开私有方法以对其进行单元测试……好主意?

本文翻译自:Making a private method public to unit test it…good idea?

Moderator Note: There are already 39 answers posted here (some have been deleted). 主持人注意: 这里已经发布了39个答案(有些已经删除)。 Before you post your answer, consider whether or not you can add something meaningful to the discussion. 发布的答案之前,请考虑是否能添加一些有意义的讨论。 You're more than likely just repeating what someone else has already said. 您很有可能只是重复别人已经说过的话。


I occasionally find myself needing to make a private method in a class public just to write some unit tests for it. 我偶尔会发现自己需要在类中公开一个私有方法,只是为此编写了一些单元测试。

Usually this would be because the method contains logic shared between other methods in the class and it's tidier to test the logic on its own, or another reason could be possible be I want to test logic used in synchronous threads without having to worry about threading problems. 通常这是因为该方法包含该类中其他方法之间共享的逻辑,并且更愿意自己测试该逻辑,或者还有另一个原因是我想测试同步线程中使用的逻辑而不必担心线程问题。

Do other people find themselves doing this, because I don't really like doing it?? 其他人是否发现自己正在这样做,因为我真的不喜欢这样做? I personally think the bonuses outweigh the problems of making a method public which doesn't really provide any service outside of the class... 我个人认为,好处超过了公开方法的问题,而该方法实际上并没有在课堂之外提供任何服务...

UPDATE 更新

Thanks for answers everyone, seems to have piqued peoples' interest. 谢谢大家的回答,似乎引起了人们的兴趣。 I think the general consensus is testing should happen via the public API as this is the only way a class will ever be used, and I do agree with this. 我认为,普遍的共识是应该通过公共API进行测试,因为这是使用类的唯一方法,我对此表示同意。 The couple of cases I mentioned above where I would do this above were uncommon cases and I thought the benefits of doing it was worth it. 我在上面提到的我在上面会做的几个案例是不常见的案例,我认为这样做的好处是值得的。

I can however, see everyones point that it should never really happen. 但是,我可以看到每个人都指出,它永远不会真正发生。 And when thinking about it a bit more I think changing your code to accommodate tests is a bad idea - after all I suppose testing is a support tool in a way and changing a system to 'support a support tool' if you will, is blatant bad practice. 而且,当我多考虑一下时,我认为更改代码以容纳测试是一个坏主意-毕竟,我认为测试在某种程度上是一种支持工具,并且如果可以的话,将系统更改为“支持支持工具”是公然的坏习惯。


#1楼

参考:https://stackoom.com/question/tGM2/公开私有方法以对其进行单元测试-好主意


#2楼

我通常将那些方法保留为protected方法,并将单元测试放在相同的程序包中(但在另一个项目或源文件夹中),在那里它们可以访问所有受保护的方法,因为类加载器会将它们放在相同的名称空间中。


#3楼

Use reflection to access the private variables if you need to. 如果需要,可以使用反射来访问私有变量。

But really, you don't care about the internal state of the class, you just want to test that the public methods return what you expect in the situations you can anticipate. 但是,实际上,您并不关心类的内部状态,只想测试公共方法在可以预期的情况下返回的预期结果。


#4楼

IMO, you should write your tests not making deep assumptions on how your class implemented inside. IMO,您应该编写测试,而不要对您的类在内部的实现方式做深入的假设。 You probably want to refactor it later using another internal model but still making the same guarantees that previous implementation gives. 您可能想稍后使用另一个内部模型对其进行重构,但仍要保证与以前的实现相同的保证。

Keeping that in mind I suggest you to focus on testing that your contract is still holds no matter what internal implementation your class currently have. 记住这一点,我建议您集中精力测试您的合同是否仍然有效,无论您的班级目前采用哪种内部实现方式。 Property based testing of your public APIs. 基于属性的公共API测试。


#5楼

Note: 注意:
This answer was originally posted for the question Is unit testing alone ever a good reason to expose private instance variables via getters? 此答案最初针对以下问题而发布的: 单独进行单元测试是否曾经是通过getter公开私有实例变量的充分理由? which was merged into this one, so it may be a tad specific to the usecase presented there. 它已合并到此示例中,因此可能是针对此处显示的用例的一点点。

As a general statement, I'm usually all for refactoring "production" code to make it easier to test. 一般而言,我通常都会重构“生产”代码以使其更易于测试。 However, I don't think that would be a good call here. 但是,我认为这不是一个好电话。 A good unit test (usually) shouldn't care about the class' implementation details, only about its visible behavior. 一个好的单元测试(通常)通常不必关心类的实现细节,而只关心其可见行为。 Instead of exposing the internal stacks to the test, you could test that the class returns the pages in the order you expect it to after calling first() or last() . 您可以在调用first()last()之后测试类是否按期望的顺序返回页面,而不是将内部堆栈暴露给测试。

For example, consider this pseudo-code: 例如,考虑以下伪代码:

public class NavigationTest {
    private Navigation nav;

    @Before
    public void setUp() {
        // Set up nav so the order is page1->page2->page3 and
        // we've moved back to page2
        nav = ...;
    }

    @Test
    public void testFirst() {
        nav.first();

        assertEquals("page1", nav.getPage());

        nav.next();
        assertEquals("page2", nav.getPage());

        nav.next();
        assertEquals("page3", nav.getPage());
    }

    @Test
    public void testLast() {
        nav.last();

        assertEquals("page3", nav.getPage());

        nav.previous();
        assertEquals("page2", nav.getPage());

        nav.previous();
        assertEquals("page1", nav.getPage());
    }
}

#6楼

in terms of unit testing, you should definitely not add more methods; 在单元测试方面,您绝对不应添加更多方法; I believe you would better make a test case just about your first() method, which would be called before each test; 我相信您最好只针对first()方法创建一个测试用例,该方法将在每次测试之前调用; then you can call multiple times the - next() , previous() and last() to see if the outcomes match your expectation. 那么您可以多次调用-next next()previous()last()来查看结果是否符合您的期望。 I guess if you don't add more methods to your class (just for testing purposes), you would stick to the "black box" principle of testing; 我猜如果您不向类中添加更多方法(仅出于测试目的),您将坚持“黑匣子”测试原则;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值