views:

1632

answers:

5

This question arise while trying to write test cases. Foo is a class within the framework library which I dont have source access to.

public class Foo{
  public final Object getX(){
  ...
  }
}

my applications will

public class Bar extends Foo{
  public int process(){
    Object value = getX();
    ...
  }
}

The unit test case is unable to initalize as I can't create a Foo object due to other dependencies. The BarTest throws a null pointer as value is null.

public class BarTest extends TestCase{
  public testProcess(){
    Bar bar = new Bar();        
    int result = bar.process();
    ...
  }
}

Is there a way i can use reflection api to set the getX() to non-final? or how should I go about testing?

+3  A: 

If your unit test case can't create Foo due to other dependencies, that might be a sign that you're not making your unit test right in the first place.

Unit tests are meant to test under the same circumstances a production code would run, so I'd suggest recreating the same production environment inside your tests. Otherwise, your tests wouldn't be complete.

Seb
That is not what unit tests are for. Unit tests are for extremely granular units of code. What you're describing sounds more like integration tests or possibly functional tests.
Hank Gay
Not necessarily; I don't know the specific circumstances in which he's working (i.e. other classes, DB, etc.), but there are certain tests you can do with many classes at once - for example, if you're using an external library, it's ok to assume it's working ok and use all its clases in your tests.
Seb
Yeah, there are "certain tests you can do with many classes at once". Those aren't unit tests. Still useful, and important to do, but they aren't **unit** tests.
Adam Jaskiewicz
"Unit", "smoke", "integration", "black box", "white box", etc. are all distractions from the original question. The dev wants to figure out whether or not they can substitute an alternative method for the framework's final. I think this exposes a flawed dependency that requires some refactoring.
gregturn
gregturn> actually the dependency was expressed intentionally as the framework dev did not want anyone to override it. Yes, you have summarised nicely my intend. thx 8)
zeroin23
+2  A: 

Seb is correct, and just to ensure that you get an answer to your question, short of doing something in native code (and I am pretty sure that would not work) or modifying the bytecode of the class at runtime, and creating the class that overrides the method at runtime, I cannot see a way to alter the "finalness" of a method. Reflection will not help you here.

TofuBeer
are you referring to Aspect-oriented aka AOP? any idea if AOP can change the access to non-final?
zeroin23
I wasn't really meaning AOP, not sure if it can do it, I was thinking more along the lines of http://jakarta.apache.org/bcel/. However, if somehting is hard to do there is probably a reason for it... and generally hard things should not be done :-)
TofuBeer
+4  A: 

you could create another method which you could override in your test:

public class Bar extends Foo {
  protected Object doGetX() {
    return getX();
  }
  public int process(){
    Object value = doGetX();
    ...
  }
}

then, you could override doGetX in BarTest.

james
A: 

If the variable returned by getX() is not final you can use the technique explained in What’s the best way of unit testing private methods? for changing the value of the private variable through Reflection.

Cem Catikkas
sadly, it is marked final... thx anyway
zeroin23
A: 
public class Bar extends Foo{
  public int process(){
    Object value = getX();
    return process2(value);
  }
  public int process2(Object value){
  ...
  }
}

public class BarTest extends TestCase{
  public testProcess(){
    Bar bar = new Bar();   
    Mockobj mo = new Mockobj();     
    int result = bar.process2(mo);
    ...
  }
}

what i did eventually was the above. it is a bit ugly... James solution is definitely much better than this...

zeroin23