Java tool for testing private methods?

前端 未结 5 2053
忘了有多久
忘了有多久 2021-02-20 10:32

There are different opinions on the meaningfulness of testing of private methods, e.g., here and here. I personally think it makes sense, the question is how to do it properly.

相关标签:
5条回答
  • 2021-02-20 11:01

    It seems like a lot of trouble to do this implementation. It may not be worth it. Rather just make the method package default.

    However, if you are determined to call private method, you can use setAccessible in yourDecapsulated_something class to allow call via reflection. So it's fairly simple.

    0 讨论(0)
  • 2021-02-20 11:06

    There are number of approaches to take

    • Don't test private methods as they are hidden implementation details which should never make a difference to the caller.
    • Make the methods package local so a caller cannot access them, but you can access them in the same package i.e. a unit test.
    • Make the unit test an inner class or provide a package local inner class. Not sure this is an improvement!
    • Use reflection to access the methods of the class. This is like marking a method rpivate when its not and is a confusion IMHO. You should be only marking a method private when it is truely private.
    0 讨论(0)
  • 2021-02-20 11:11

    I'll answer the "In general" question :-) It only takes a few lines of code to make a method accessible via reflection and there are quite a number of libraries, utils, APIs etc that provide methods for doing so. There's also probably many different techniques you could use in your own code. For example bytecode manipulation, reflection, class extensions, etc. But I'd be inclined to keep things simple. Whilst it can be useful to test private methods, it's also likely that you will only want to test a few. So engineering something complex is probably overkill. I'd just use an established API, or write a quick method to access the private methods I was interested in and let it be done at that.

    0 讨论(0)
  • 2021-02-20 11:15

    it would be nice to be able to call private methods in the test code like

    @MakeVisibleForTesting Something something = new Something();
    Assert.assertEquals(43, something.internalSecret());
    

    There's such thing as a method annotation, check out dp4j's @TestPrivates:

    @Test
    @TestPrivates 
    //since the method is annotated with JUnit's @Test this annotation is redundant. 
    // You just need to have dp4j on the classpath.
        public void somethingTest(){
          Something something = new Something();
          int sthSecret = something.internalSecret();
           Assert.assertEquals(43, sthSecret); //cannot use something.internalSecret() directly because of bug [dp4j-13][2] 
        }
    
    0 讨论(0)
  • 2021-02-20 11:17

    I worked on a project a few years back that generated classes to make it easier to unit test private methods. http://java.net/projects/privateer/

    It generated extra classes that made it easier than calling reflection, e.g. if you had MyClass.myPrivateMethod() it would generate a _MyClass class that would allow invocation of myPrivateMethod directly.

    It was never really finished and was kind of useful for a few cases, but overall I wouldn't recommend testing private methods unless absolutely necessary. Usually redesigning them into utility classes (with package access if you're worried about users using them) is a better option.

    0 讨论(0)
提交回复
热议问题