简体   繁体   中英

public method returns private class instance in Java?

I have a method that returns an instance of a private class and I need access to its methods from a different package for unit testing. These classes live in the same file. It goes like this:

file: A.java

public class A{
    B b;
    public B getB(){
        return b;
    }  
    public setB(B b){
        this->b = b;
   }
}

class B{
    C c;
    public C getC(){
        return c;
    }
    public setC(C c){
        this->c = c;
   }
}

class C{
    public int getInt(){
        return 1;
    }
}

So... Basically the question is: are any of the methods in B or C reachable somehow? Am I obligated to place B and C in different files and make them public to accomplish that?

It is best practice to ALWAYS put the source code for each top level class in a separate file. If you don't do this, you may run into difficulties with compiling, etc.

There is a separate issue of whether the classes B and C need to be public so that you can create unit tests. I'd say it is probably a good idea, but there are a couple of ways around this:

  • If you put the unit tests in the same Java package as the classes A , B and C , then the classes (and their methods) will be visible to the unit tests.

  • You could expose the methods by creating public subclasses of B and C for test purposes. These have to be declare in the same Java package as the classes A , B and C .

  • You could create instances of B and C and call methods on them using reflection. (But this is a lot of work for a unit test, and I would NOT recommend it!)

Note that if you have separate source directory trees for your product code and your test code, you can put test classes into the same package as A , B and C without mixing up the codebases. When you build for production / release, you just leave the classes in the test tree out of the build.


By the way, in your example the classes B and C are "package private" rather than "private". Unit testing a real "private" class is a whole different problem.

You want to use Reflection to test private methods with unit testing. You can read more here(see answer):

How do I test a class that has private methods, fields or inner classes?

Yes, you can use reflection to invoke all methods in any instance of B or C anywhere, but this, from my POV, is a hack rather than a technique.

Otherwise, class B and C are not exposed outside your A.class .

Technically the classes are protected; so as long as classes that call getB and getC are within the same package you won't have any issues. If from another package you tried to run GetB GetC you are going to see some issues because your other package will not be able to access the actual class.

Here TestProt CANNOT be imported since it is protected in the tester2 package. FILE1:

package tester; 
import tester2.Test; 
public class Testing {   
  public Testing() {
    Test t = new Test();
    TestProt p = t.prot();   
  } 
}

FILE2:

package tester2;
public class Test {
  public TestProt prot() {
    return new TestProt();
  } 
}

class TestProt{
  public TestProt() {
  } 
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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