I'm testing out an android app, and am using a library provided to me by my university, classes 1-4 come from my lecturer for our use.
I have a class structured like so:
ClassOne
public ClassOne {
private ClassTwo clsTwo;
...
public ClassOne(ClassTwo p1)
public ClassTwo getClsTwo();
}
ClassTwo is structured as so:
public ClassTwo {
private ClassThree clsThree;
...
public ClassTwo()
public ClassThree getClsThree();
}
ClassThree is structured as so:
public ClassThree {
private HashMap<Bitmap> mBitmaps;
...
private ClassFour clsFour;
...
public ClassThree(ClassFour p1);
...
public loadFile(String path, String name);
public loadFileFromAssetStore(String name);
}
ClassFour is structured as so:
public ClassFour {
...
public ClassFour(Context context);
...
}
The Class I am testing is ClassFive, which specifically has the methods highlighted which are causing issues:
public ClassFive {
private Bitmap myBitmap
...
public ClassFive(...,...,...,ClassOne p,...){
super(..., p,
p.getClsTwo().getClsThree().loadFileFromAssetStore("Default value"));
this.myBitmap = loadCorrectFile(...,p);
}
private Bitmap loadCorrectFile(..., ClassOne p){
String strCorrectFileName;
switch(...){
...
// set value of strCorrectFileName
...
}
this.myBitmap = p.getClsTwo().getClsThree().loadFileFromAssetStore(strCorrectFileName);
}
}
My problem is I need to test methods using constructor of ClassFive, however the tests are all 'falling over' when invoking the constructor with a NPE.
public class ClassFiveTest {
#Mock
private ClassOne mockClassOne = Mockito.Mock(ClassOne.class);
#Test
public void testConstructorGetName() throws Exception {
ClassFive instance = new ClassFive(..., mockClassOne);
...
// Assertions here
...
}
My problem is that a null pointer exception is being returned before my test can get to my assertions. Do I need to be using mockito? Because I tried that - maybe I'm just using it wrong for this instance. Or do I need to be using instrumented tests? When I tried instrumented testing I found it impossible to get access to ClassOne and ClassTwo?
This is easily remedied with some stubbing.
#Mock private ClassOne mockClassOne; // Don't call `mock`; let #Mock handle it.
#Mock private ClassTwo mockClassTwo;
#Mock private ClassThree mockClassThree;
#Override public void setUp() {
MockitoAnnotations.initMocks(this); // Inits fields having #Mock, #Spy, and #Captor.
when(mockClassOne.getClsTwo()).thenReturn(mockClassTwo);
when(mockClassTwo.getClsThree()).thenReturn(mockClassThree);
// Now that you can get to mockClassThree, you can stub that too.
when(mockClassThree.loadFileFromAssetStore("Default value")).thenReturn(...);
when(mockClassThree.loadFileFromAssetStore("Your expected filename")).thenReturn(...);
}
In summary, Mockito is designed for easily making replacement instances of classes so you can check your interactions with your class-under-test: Here, you're creating fake ("test double") implementations of ClassOne, ClassTwo, and ClassThree, for the purpose of testing ClassFive. (You might also choose to use real implementations or manually-written fake implementations, if either of those make more sense for your specific case than Mockito-produced implementations.) Unless you otherwise stub them, Mockito implementations return dummy values like zero or null for all implemented methods, so trying to call getClsThree on the null returned by getClsTwo causes an NPE until you stub getClsTwo otherwise.
If the stubs for mockThree change between tests, you can move them into your test before you initialize your ClassFive. I'm also sticking to JUnit3 syntax and explicit initMocks above, because Android instrumentation tests are stuck on JUnit3 syntax if you're not using the Android Testing Support Library; for tests on JUnit4 or with that library you can use a cleaner alternative to initMocks. Once you get comfortable with Mockito, you can also consider RETURNS_DEEP_STUBS, but I like to keep my stubs explicit myself; that documentation also rightly warns "every time a mock returns a mock, a fairy dies".
Isn't this long and complicated, and doesn't it feel unnecessary? Yes. You are working around violations of the Law of Demeter, which Wikipedia summarizes (emphasis mine) as:
Each unit should have only limited knowledge about other units: only units "closely" related to the current unit.
Each unit should only talk to its friends; don't talk to strangers.
Only talk to your immediate friends.
Your problem and your verbose solution both stem from ClassFive depending on ClassThree, but only via ClassOne and ClassTwo implementation details. This isn't a strict law, but in your own code outside of university you might treat this as a sign to revisit the designs of ClassOne, ClassTwo, and ClassFive and how they interact. If ClassFive were to depend directly on ClassThree, it may be easier to work with the code in production and tests, and maybe you'd find that ClassOne isn't necessary at all.
// ClassFive doesn't just work with its dependency ClassOne, it works directly with its
// dependency's dependency's dependency ClassThree.
super(..., p,
p.getClsTwo().getClsThree().loadFileFromAssetStore("Default value"));
I'd like to support the answer of#JeffBowman by showing how the code could look like.
The proposed solution implies that you add another parameter to the constructors parameter list with is far to long already. Your code could be simplified by following the Favor composition over inheritance principle
Most parameters of the constructor in ClassFive are only there to be pass to the parent classes constructor.
In this situation it would be better not to inherit from that super class, but create an interface (e.g.: extract with support of your IDE) of the super class (lets call is SuperInterface that is implemented by both, the super class and CLassFive.
The you replace all the parameters that are passed to the super class by one single parameter of type SuperInterface.
Then you simply delegate all methods of SuperInterface that are not implemented by CLassFive directly to the SuperInterface instance.
This is what it would look like:
public interface SuperInterface {
// all public methods of the super class.
}
public class ClassFive implements SuperInterface{
private final SuperInterface superClass;
private final Bitmap myBitmap
public ClassFive(SuperInterface superClass ,ClassTree p){
this.superClass = superClass;
p.loadFileFromAssetStore("Default value"));
this.myBitmap = loadCorrectFile(...,p);
}
#Override
public void someMethodDeclaredInInterface(){
this.superClass.someMethodDeclaredInInterface();
}
}
This pattern also works vice versa if you don't like the duplicated method delegations all over your classes extending SuperInterface.
This alternative approach is useful if your specializations override just a few methods of the interface and almost all the same.
In that case the interface you create may not be implemented by the super class. The methods declared in the interface don't even need to be part of the super classes public methods. The interface only declares methods that the super class (should now better be called "generic class") needs to use the derived behavior.
This would look like this:
interface AnimalSound{
String get();
}
class DogSound implements AnimalSound{
#Override
public String get(){
return "wouff";
}
}
class CatSound implements AnimalSound{
#Override
public String get(){
return "meaw";
}
}
class Animal {
private final AnimalSound sound;
public Animal(AnimalSound sound){
this.sound = sound;
}
public String giveSound(){
return sound.get();
}
}
And this is how we use it:
List<Animal> animals = new ArrayList<>();
animals.add(new Animal(new DogSound()));
animals.add(new Animal(new CatSound()));
for(Animal animal : animals){
System.out.println(animal.giveSound());
}
Related
This seems like a newbish question, but the last time I worked with Java, the language didn't have generics. I have a class hierarchy (names changed to be as generalized as possible):
public abstract class AbstractBase { .... }
public class ConcreateSubA extends AbstractBase { .... }
public class ConcreateSubB extends AbstractBase { .... }
...
public class ConcreateSubZZ9PluralZAlpha extends AbstractBase { .... }
...
I'm trying to clean up some legacy code, and there's one place where a ton of repetitive duplication can all be factored out into a single routine via generics. (I'm thinking generics because when this routine is called, it needs to operate on only one of the concrete classes.)
The routine looks like
public <Thing extends AbstractBase> void someFunc()
{
another_function_call (Thing.concreteSpecialToken);
// could also be
// another_function_call (Thing.concreteSpecialToken());
// if methods are more feasible than fields
// Cannot use
// another_function_call (Thing().concreteSpecialToken());
// because creating instances of these types is a Major Operation[tm]
}
I'm leaving out about a zillion lines, but that's the important part: someFunc() is type parametric (it actually takes arguments but none of them are Things so no inference). Eventually I need to fetch a special token and this is where I'm getting fuzzy.
The tokens are huge-ass unique strings for each concrete class. They're class-based, not instance-based. The actual token value is declared as a private static final field in each subclass.
So I need to use the public methods/fields of a base class to (eventually) get to the private static field of a subclass. Obviously I can't declare an abstract static method in the base, because that makes no sense. If the data were instance-based, then this would be trivial, with a polymorphic getter in the base class, but the subclass stuff is static.
I feel like I'm missing a feature of Java generics here, but I can't use Thing.whatever() unless the whatever is something that's possible to declare in the abstract base class. I'm running up against either limitations of Java or my lack of expertise trying to bridge the gap. The one attempt I made that seemed promising also had a ton of code duplication all the way down the class hierarchy, defining abstract methods with the exact same code over and over... which is what generics are supposed to help prevent!
I'm running up against either limitations of Java or my lack of expertise trying to bridge the gap.
It's a limitation of Java, although a fairly reasonable one IMO. Basically you're still trying to use static members as if they were polymorphic, and that's not going to work - generics don't help you there.
Options:
Use reflection... but bear in mind that type erasure means you can't get at the Class for Thing unless you pass it in explicitly
If you've got an instance of Thing anyway, just make it an abstract instance member, which in each implementation happens to return the value of a static field
Create a separate type hierarchy which will use instance members
If I understand it correctly, you need the concrete class of the type parameter. The usual way of doing it is to declare your method like this: public <T extends AbstractBase> void someFunc(Class<T> clazz)
This of course means an extra parameter needs to be passed to the method and you need to use reflection to access the static fields, but given Java's type erasure it's the only way.
The moral of the story is that generics and statics don't go very well together.
A bit clunky but if someFunc took a Class<Thing> parameter you could use reflection:
public <Thing extends AbstractBase> void someFunc(Class<Thing> clz) {
// exception handling omitted
Object whatever = clz.getDeclaredMethod("whatever").invoke(null);
But you could maybe take better advantage of polymorphism by using nested classes, something like
public abstract class AbstractBase {
public static class Info {
public String getInfo() {
return "AbstractBase";
}
}
}
public class ConcreteSubA extends AbstractBase {
public static final Info INFO = new Info() {
public String getInfo() { return "ConcreteSubA"; }
}
}
and have someFunc take an AbstractBase.Info parameter.
public <Thing extends AbstractBase> someFunc(AbstractBase.Info inf) {
String info = inf.getInfo();
}
// call it as
ConcreteSubB csb = someFunc(ConcreteSubB.INFO);
The idea is that each class in the hierarchy has a singleton instance of Info holding its formerly-static data.
If you want to keep the token as it is, a private static final field, you can get it through reflection:
public <Thing extends AbstractBase> void someFunc(Class<Thing> clz)
{
try {
Field field = clz.getField("concreteSpecialToken");
field.setAccessible(true);
Object concreteSpecialToken = field.get(null);
another_function_call (concreteSpecialToken);
} catch (IllegalAccessException e) {
handle(e);
} catch (NoSuchFieldException e) {
handle(e);
}
}
At call site, you have to do someFunc(ConcreateSubZZ9PluralZAlpha.class). But I wonder if you can do that, why don't you just pass the token object as a parameter, as in someFunc(ConcreateSubZZ9PluralZAlpha.concreteSpecialToken)? Or maybe even move the method someFunc() to the token class itself.
I have an abstract class inherited by two concrete classes.
public abstract class AbstractClass {
public abstract void operation1();
}
public class ConcreteClassA extends AbstractClass {
#Override
public void operation1() {
// Do work
}
public void operation2() {
// Do some other work
}
}
public class ConcreteClassB extends AbstractClass {
#Override
public void operation1() {
// Do work
}
}
Now, to take advantage of dynamic binding I create two objects while programming to the interface.
private AbstractClass classA = new ConcreteClassA();
private AbstractClass classB = new ConcreteClassB();
But this does not allow me to call method operation2() on classA. I can fix this by using a downcast.
((ConcreteClassA) classA).operation2();
But downcasts are considered ugly in OOP especially when you have to use them a lot. Alternatively, I can give up programming to the interface.
private ConcreteClassA classA = new ConcreteClassA();
But then I lose the dynamic binding. Another option is to move operation2() to the AbstractClass so that I can restore the dynamic binding.
public abstract class AbstractClass {
public abstract void operation1();
public abstract void operation2();
}
But then ConcreteClassB needs to override operation2() leaving the implementation empty since this class does not need this method.
Lastly, I could move operation2() to the AbstractClass and provide a default implementation which may be overridden or not.
public abstract class AbstractClass {
public abstract void operation1();
public void operation2() {
// Some default implementation
}
}
But this gives classB access to operation2() which I would rather avoid.
There does not seem to be a clean solution to call subclass specific methods while maintaining dynamic binding at the same time. Or is there?
There are at least a few ways to deal with this circumstance and, really, the right one depends on your particular requirements.
Ask yourself, "are both operation1 and operation2 part of the contract specified by my type?"
If the answer is clearly no, then you should not pollute the contract of your type by adding collateral methods to it. You should next ask yourself, "why am I not using interfaces to specify separate types, eg.: instead of AbstractClass, why am I not using MyInterface1 and MyInterface2 (each with its own separate contract)? Interfaces provide a limited form of multiple inheritance, and your implementing classes can implement any and all interfaces that pertain to it. This is a strategy commonly used by the Java Platform Libraries. In this circumstance, explicit casting to the type whose contract you want to use is exactly the right thing to do.
If the answer is clearly yes, then you should have both methods in your type ... but you should still ask yourself, "why am I not specifying my type with an interface"? In general, you should specify types with interfaces rather than abstract classes, but there are reasons to use the latter.
If the answer is somewhere in between, then you can consider specifying optional methods in your type. These are methods which are included in the contract of your type, but which implementing classes are not required to implement. Before Java 8, each implementing type would need to throw a UnsupportedOperationException for any optional methods that it did not implement. In Java 8, you can do something like this for optional methods:
======
public interface MyType {
void contractOperation1();
default void optionalOperation2() {
throw new UnsupportedOperationException();
}
}
A class that implements this interface will need to provide an implementation for contractOperation1(). However, the class will not need to provide an implementation for optionalOperation2() and if this method is invoked on an implementing class that has provided no implementation of its own, then the exception is thrown by default.
abstract class don't have the object,we just create the reference of that class and use it.
like:
instead of this-
private AbstractClass classA = new ConcreteClassA();
private AbstractClass classB = new ConcreteClassB();
use this one
private AbstractClass classA;
private AbstractClass classB;
If we will create an object of the abstract class and calls the method having no body(as the method is pure virtual) it will give an error. That is why we cant create object of abstract class. Here is a similar StackOverflow question. In short, it is legal to have a public constructor on an abstract class.
more details are here:about abstraction instance
This seems like a newbish question, but the last time I worked with Java, the language didn't have generics. I have a class hierarchy (names changed to be as generalized as possible):
public abstract class AbstractBase { .... }
public class ConcreateSubA extends AbstractBase { .... }
public class ConcreateSubB extends AbstractBase { .... }
...
public class ConcreateSubZZ9PluralZAlpha extends AbstractBase { .... }
...
I'm trying to clean up some legacy code, and there's one place where a ton of repetitive duplication can all be factored out into a single routine via generics. (I'm thinking generics because when this routine is called, it needs to operate on only one of the concrete classes.)
The routine looks like
public <Thing extends AbstractBase> void someFunc()
{
another_function_call (Thing.concreteSpecialToken);
// could also be
// another_function_call (Thing.concreteSpecialToken());
// if methods are more feasible than fields
// Cannot use
// another_function_call (Thing().concreteSpecialToken());
// because creating instances of these types is a Major Operation[tm]
}
I'm leaving out about a zillion lines, but that's the important part: someFunc() is type parametric (it actually takes arguments but none of them are Things so no inference). Eventually I need to fetch a special token and this is where I'm getting fuzzy.
The tokens are huge-ass unique strings for each concrete class. They're class-based, not instance-based. The actual token value is declared as a private static final field in each subclass.
So I need to use the public methods/fields of a base class to (eventually) get to the private static field of a subclass. Obviously I can't declare an abstract static method in the base, because that makes no sense. If the data were instance-based, then this would be trivial, with a polymorphic getter in the base class, but the subclass stuff is static.
I feel like I'm missing a feature of Java generics here, but I can't use Thing.whatever() unless the whatever is something that's possible to declare in the abstract base class. I'm running up against either limitations of Java or my lack of expertise trying to bridge the gap. The one attempt I made that seemed promising also had a ton of code duplication all the way down the class hierarchy, defining abstract methods with the exact same code over and over... which is what generics are supposed to help prevent!
I'm running up against either limitations of Java or my lack of expertise trying to bridge the gap.
It's a limitation of Java, although a fairly reasonable one IMO. Basically you're still trying to use static members as if they were polymorphic, and that's not going to work - generics don't help you there.
Options:
Use reflection... but bear in mind that type erasure means you can't get at the Class for Thing unless you pass it in explicitly
If you've got an instance of Thing anyway, just make it an abstract instance member, which in each implementation happens to return the value of a static field
Create a separate type hierarchy which will use instance members
If I understand it correctly, you need the concrete class of the type parameter. The usual way of doing it is to declare your method like this: public <T extends AbstractBase> void someFunc(Class<T> clazz)
This of course means an extra parameter needs to be passed to the method and you need to use reflection to access the static fields, but given Java's type erasure it's the only way.
The moral of the story is that generics and statics don't go very well together.
A bit clunky but if someFunc took a Class<Thing> parameter you could use reflection:
public <Thing extends AbstractBase> void someFunc(Class<Thing> clz) {
// exception handling omitted
Object whatever = clz.getDeclaredMethod("whatever").invoke(null);
But you could maybe take better advantage of polymorphism by using nested classes, something like
public abstract class AbstractBase {
public static class Info {
public String getInfo() {
return "AbstractBase";
}
}
}
public class ConcreteSubA extends AbstractBase {
public static final Info INFO = new Info() {
public String getInfo() { return "ConcreteSubA"; }
}
}
and have someFunc take an AbstractBase.Info parameter.
public <Thing extends AbstractBase> someFunc(AbstractBase.Info inf) {
String info = inf.getInfo();
}
// call it as
ConcreteSubB csb = someFunc(ConcreteSubB.INFO);
The idea is that each class in the hierarchy has a singleton instance of Info holding its formerly-static data.
If you want to keep the token as it is, a private static final field, you can get it through reflection:
public <Thing extends AbstractBase> void someFunc(Class<Thing> clz)
{
try {
Field field = clz.getField("concreteSpecialToken");
field.setAccessible(true);
Object concreteSpecialToken = field.get(null);
another_function_call (concreteSpecialToken);
} catch (IllegalAccessException e) {
handle(e);
} catch (NoSuchFieldException e) {
handle(e);
}
}
At call site, you have to do someFunc(ConcreateSubZZ9PluralZAlpha.class). But I wonder if you can do that, why don't you just pass the token object as a parameter, as in someFunc(ConcreateSubZZ9PluralZAlpha.concreteSpecialToken)? Or maybe even move the method someFunc() to the token class itself.
I am new to Java testing with JUnit. I have to work with Java and I would like to use unit tests.
My problem is: I have an abstract class with some abstract methods. But there are some methods which are not abstract. How can I test this class with JUnit? Example code (very simple):
abstract class Car {
public Car(int speed, int fuel) {
this.speed = speed;
this.fuel = fuel;
}
private int speed;
private int fuel;
abstract void drive();
public int getSpeed() {
return this.speed;
}
public int getFuel() {
return this.fuel;
}
}
I want to test getSpeed() and getFuel() functions.
Similar question to this problem is here, but it is not using JUnit.
In JUnit FAQ section, I found this link, but I don't understand what the author want to say with this example. What does this line of code mean?
public abstract Source getSource() ;
If you have no concrete implementations of the class and the methods aren't static whats the point of testing them? If you have a concrete class then you'll be testing those methods as part of the concrete class's public API.
I know what you are thinking "I don't want to test these methods over and over thats the reason I created the abstract class", but my counter argument to that is that the point of unit tests is to allow developers to make changes, run the tests, and analyze the results. Part of those changes could include overriding your abstract class's methods, both protected and public, which could result in fundamental behavioral changes. Depending on the nature of those changes it could affect how your application runs in unexpected, possibly negative ways. If you have a good unit testing suite problems arising from these types changes should be apparent at development time.
Create a concrete class that inherits the abstract class and then test the functions the concrete class inherits from the abstract class.
With the example class you posted it doesn't seem to make much sense to test getFuel() and getSpeed() since they can only return 0 (there are no setters).
However, assuming that this was just a simplified example for illustrative purposes, and that you have legitimate reasons to test methods in the abstract base class (others have already pointed out the implications), you could setup your test code so that it creates an anonymous subclass of the base class that just provides dummy (no-op) implementations for the abstract methods.
For example, in your TestCase you could do this:
c = new Car() {
void drive() { };
};
Then test the rest of the methods, e.g.:
public class CarTest extends TestCase
{
private Car c;
public void setUp()
{
c = new Car() {
void drive() { };
};
}
public void testGetFuel()
{
assertEquals(c.getFuel(), 0);
}
[...]
}
(This example is based on JUnit3 syntax. For JUnit4, the code would be slightly different, but the idea is the same.)
If you need a solution anyway (e.g. because you have too many implementations of the abstract class and the testing would always repeat the same procedures) then you could create an abstract test class with an abstract factory method which will be excuted by the implementation of that test class. This examples works or me with TestNG:
The abstract test class of Car:
abstract class CarTest {
// the factory method
abstract Car createCar(int speed, int fuel);
// all test methods need to make use of the factory method to create the instance of a car
#Test
public void testGetSpeed() {
Car car = createCar(33, 44);
assertEquals(car.getSpeed(), 33);
...
Implementation of Car
class ElectricCar extends Car {
private final int batteryCapacity;
public ElectricCar(int speed, int fuel, int batteryCapacity) {
super(speed, fuel);
this.batteryCapacity = batteryCapacity;
}
...
Unit test class ElectricCarTest of the Class ElectricCar:
class ElectricCarTest extends CarTest {
// implementation of the abstract factory method
Car createCar(int speed, int fuel) {
return new ElectricCar(speed, fuel, 0);
}
// here you cann add specific test methods
...
I would create a jUnit inner class that inherits from the abstract class. This can be instantiated and have access to all the methods defined in the abstract class.
public class AbstractClassTest {
public void testMethod() {
...
}
}
class ConcreteClass extends AbstractClass {
}
You could do something like this
public abstract MyAbstractClass {
#Autowire
private MyMock myMock;
protected String sayHello() {
return myMock.getHello() + ", " + getName();
}
public abstract String getName();
}
// this is your JUnit test
public class MyAbstractClassTest extends MyAbstractClass {
#Mock
private MyMock myMock;
#InjectMocks
private MyAbstractClass thiz = this;
private String myName = null;
#Override
public String getName() {
return myName;
}
#Test
public void testSayHello() {
myName = "Johnny"
when(myMock.getHello()).thenReturn("Hello");
String result = sayHello();
assertEquals("Hello, Johnny", result);
}
}
You can instantiate an anonymous class and then test that class.
public class ClassUnderTest_Test {
private ClassUnderTest classUnderTest;
private MyDependencyService myDependencyService;
#Before
public void setUp() throws Exception {
this.myDependencyService = new MyDependencyService();
this.classUnderTest = getInstance();
}
private ClassUnderTest getInstance() {
return new ClassUnderTest() {
private ClassUnderTest init(
MyDependencyService myDependencyService
) {
this.myDependencyService = myDependencyService;
return this;
}
#Override
protected void myMethodToTest() {
return super.myMethodToTest();
}
}.init(myDependencyService);
}
}
Keep in mind that the visibility must be protected for the property myDependencyService of the abstract class ClassUnderTest.
You can also combine this approach neatly with Mockito. See here.
My way of testing this is quite simple, within each abstractUnitTest.java. I simply create a class in the abstractUnitTest.java that extend the abstract class. And test it that way.
You can not test whole abstract class. In this case you have abstract methods, this mean that they should be implemented by class that extend given abstract class.
In that class programmer have to write the source code that is dedicated for logic of his.
In other words there is no sens of testing abstract class because you are not able to check the final behavior of it.
If you have major functionality not related to abstract methods in some abstract class, just create another class where the abstract method will throw some exception.
As an option, you can create abstract test class covering logic inside abstract class and extend it for each subclass test. So that in this way you can ensure this logic will be tested for each child separately.
You don't need a fancy Mockito add on, or anonymous classes, or whatever other things the other answers are recommending. Junit supports test classes extending each other: so, write a thorough, abstract test class (literally just make the test class abstract) for your abstract base class, that examines how each of the methods behave. Do these tests on a set of instance-variable objects, that are set up as you desire in an #BeforeEach method in this base test class. Have that method call an abstract allocateObjects() method, which will do all the object allocation.
Then, for each class that extends your abstract base, have a test class that extends the abstract test class you just wrote. This test class will do the actual object allocation in the overridden allocateObjects() method. The objects it allocates will be used by the methods in the parent test class: methods which are inhertied by this test class, and therefore run as a part of its testing.
Could you do factory tomfoollery? I guess: but since you probably need to create test classes for each subclass anyways, you might as well just keep things simple with inheritence. I suppose if you have a lot of subclasses, and none of them do anything that is worth testing appart from the superclass stuff, it would be worth it: but why on earth would you be creating subclasses in that case?
Instead of doing #inject mock on abstract class create a spy and create a anonymous implementation in the test class itself and use that to test your abstract class.Better not to do that as there should not be any public method on with you can do unit test.Keep it protected and call those method from implemented classes and test only those classes.
I have an abstract Java class MyAbstractClass with a private method. There is a concrete implementation MyConcreteClass.
public class MyAbstractClass {
private void somePrivateMethod();
}
public class MyConcreteClass extends MyAbstractClass {
// implementation details
}
In my groovy test class I have
class MyAbstractClassTest {
void myTestMethod() {
MyAbstractClass mac = new MyConcreteClass()
mac.somePrivateMethod()
}
}
I get an error that there is no such method signature for somePrivateMethod. I know groovy can call private methods but I'm guessing the problem is that the private method is in the super class, not MyConcreteClass. Is there a way to invoke a private method in the super class like this (other than using something like PrivateAccessor)?
thanks
Jeff
The fact that you can call private methods is a bug in the Groovy language, not a feature. However, I believe this bug was introduced deliberately as a form of compromise when making some changes to the way closures behave.
Even though you can call private methods, you should not, because hopefully one day this bug will be fixed, and if your program relies on calling private methods it will be broken.
If you really insist on (ab)using this undocumented behaviour, you could try using something like ReflectionUtils to call private methods in parent classes.
Another workaround is to provide a method in the concrete class that calls the private method in the parent class. For example, the following code "works", but it still relies on accessing private members, which is bad
class Parent {
private foo() {println "foo"}
}
class Child extends Parent {
public bar() {super.foo()}
}
new Child().bar()