Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test abstract class in Java with JUnit?

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() ; 
like image 779
vasco Avatar asked Sep 27 '11 12:09

vasco


People also ask

Can you JUnit test an abstract class?

With JUnit, you can write a test class for any source class in your Java project. Even abstract classes, which, as you know, can't be instantiated, but may have constructors for the benefit of “concrete” subclasses.

Can you test an abstract class in Java?

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.

Can we mock an abstract class?

So there is NO way to mock an abstract class without using a real object implementation (e.g inner class definition in unit test class, overriding abstract methods) and spying the real object (which does proper field initialization).

How do you inject a mock in an abstract class?

Mocking abstract class using PowerMock mock() is a better approach as it can have control over the private as well as static methods. Step1: Create an abstract class named Abstract_class that contains both abstract and non-abstract methods. Step 2: Create a JUnit test case named AbstractTestClass for testing purposes.


2 Answers

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.

like image 156
nsfyn55 Avatar answered Sep 20 '22 16:09

nsfyn55


Create a concrete class that inherits the abstract class and then test the functions the concrete class inherits from the abstract class.

like image 44
Kevin Bowersox Avatar answered Sep 17 '22 16:09

Kevin Bowersox