Having helper methods in junit class - java

I want to unit test a class, Class A, but it has a dependency on another class that uses a user session method. The method that I want to test does not involve user session. Can I make helper method in Class A that would replicate the behavior of the Class B method that I need?
I know it's not clear, let's dig some code to get clear understanding....
public void testDetails() throws Exception
{
//Some logic that generates DetailsTOList
saveDetailsHelper(DetailsTOList);
int detailsSize = getDetailsSize();
assertNotNull(detailsSize);
}
Now getDetailsSize() get size information from a database. Class B has this method, but I cannot create an object of Class B and test this method since Class B gets session information from User, and I can set session information from JUnit class.
I have created saveDetailsHelper method that replicates behavior of Class B - saveDetails() method, and am calling that in testDetails() method as shown above.
My question:
can we have helper methods in junit class?
What is best approach to deal with this situation?

JUnit classes function like every other class in java; you're welcome to have helper functions. The only thing that determines whether other functions will be run is (depending on the version of junit) whether or not there is an annotation instructing the harness to run it as a test.
However, this problem is precisely why you should design your classes carefully. If Class B calls out to a database for information, this is a great opportunity to compartmentalize that functionality. You don't clarify 'dependency' (are you extending?), but if Class B is a component of Class A, you can create a whole stub class that is a stand in for Class B, and returns hardcoded (or otherwise coded) data specifically for the testing of class A. As long as the signature of the Class B proxy is the same, you can have confidence Class A works.
It is often useful to make these inner classes of your test class, to keep things from getting too messy in your workspace.
public class testA {
#Test
public void testDetails {
ClassA a = new ClassA();
a.setDependency(new StubClassB());
//run your test
}
private class StubClassB() extends ClassB {
public boolean saveDetails() {
//return fake information;
}
}
}

Helper methods will not have the #Testcase annotation. You would write the test code just like any other code, but would include only the relevant methods for testing, and validate only relevant portions of that test method.

You can put the helper method in the test class, omit the Testcase annotation and call it where needed (ad hoc per method or in your setup if it's needed for all tests). But probably a better solution is to use something like JMock to represent Class B and give back desired results.

Related

In Java unit testing, how to mock the variables that are not injected but created inside the to-be-tested class?

For example, the class to be tested is
public class toBeTested {
private Object variable;
public toBeTested(){
variable = someFactory(); // What if this someFactory() sends internet request?
// Can I mock "variable" without calling
// someFactory() in testing?
}
public void doSomething(){
...
Object returnedValue = variable.someMethod(); // In testing, can I mock the behavior of
// this someMethod() method when
// "variable" is a private instance
// variable that is not injected?
Object localVariable = new SomeClass(); // Can I mock this "localVariable" in
// testing?
...
}
}
My questions are as stated in the comments above.
In short, how to mock the variables that are not injected but created inside the to-be-tested class?
Thanks in advance!
Your question is more about the design, the design of your class is wrong and it is not testable, It is not easy (and sometimes it is not possible at all) to write a unit test for a method and class that have been developed before. Actually one of the great benefit of TDD(Test Driven Development) is that it helps the developer to develop their component in a testable way.
Your class would have not been developed this way if its test had been written first. In fact one of the inevitable thing that you should do when you are writing test for your component is refactoring. So here to refactor your component to a testable component you should pass factory to your class's constructor as a parameter.
And what about localVariable:
It really depends on your situation and what you expect from your unit to do (here your unit is doSomething method). If it is a variable that you expext from your method to create as part of its task and it should be created based on some logic in method in each call, there is no problem let it be there, but if it provides some other logic to your method and can be passed as parameter to your class you can pass it as parameter to your class's cunstructor.
One more thing, be carefull when you are doing refactoring there will be many other components that use your component, you should do your refactoring step by step and you should not change the logic of your method.
To add another perspective: If faced with situations in which you have to test a given class and aren't permitted to change the class you need to test, you have the option to use a framework like PowerMock (https://github.com/powermock/powermock) that offers enhanced mocking capabilities.
But be aware that using PowerMock for the sole purpose of justifying hard to test code is not advisable. Tashkhisi's answer is by far the better general purpose approach.

Mocking a non-abstract method of an abstract class

I am trying to unit-test a class that extends an abstract base class.
Here are the "similar classes" for illustration purposes:
public abstract class MyAbstractBaseClass {
#Autowired
private WaterFilter waterFilter;
protected List<String> filterComponents(List<String> allComponents) {
return waterFilter.filter(allComponents);
}
}
public class MyDerivedClass extends MyAbstractBaseClass {
public List<String> filterWater(List<String> allWaterComponents) {
List<String> filteredComponents = this.filterComponents(allWaterComponents); //calls abstract class's filterComponets()
filteredComponents.add("something-else");
return filteredComponents;
}
}
Here is the unit test I am trying:
#RunWith(EasyMockRunner.class)
public class MyDerivedClassTest {
#TestSubject
private MyDerivedClassTest SUT;
#Before
public void setup() {
SUT = new MyDerivedClassTest();
}
#Test
public void test filterWater_HappyCase() {
//I want to mock my abstract class's filterComponents() method
//I am trying this:
EasyMock.expect(SUT.filterComponents(getDummyComponents())).andReturn(getSomeComponents());
//What to replay here?
//EasyMock.replay(...)
List<String> actualResult = SUT.filterWater(getDummyComponents());
//assert something
//What to verify?
//EasyMock.verify(...)
}
}
When I run this test, I get
java.lang.NullPointerException
in MyAbstractBaseClass.filter(allComponents)
I understand that the autowired "waterFilter" is not getting initialized. But then, I just want to mock the "non-abstract" method of the abstract class in my unit test.
How should I go about this using EasyMock? Also, I don't know what to replay() and verify().
When you write an unit test, you test a object (generally, a method of it) and you may mock a object (generally, a method of it).
However, you should not unit test and mock the same object because in a some way, it seems not very natural : if you test a method of a class, the behavior of the tested class should stay as natural as possible and not fake its own methods.
Otherwise, we can wonder if the quality of the unit test is good.
Why ? Because it doesn't reflect the real behavior of the class that we would have at the runtime, but just some part of its behavior.
In a unit test, isolation is researched but behind it, the idea is to isolate your under test class only from the other classes and not an isolation of its own behavior.
Of course, you can try to mock a no-abstract method in the abstract class of your under tested class but the design and the quality of your test may become less good.
In your case, I imagine two reasons to mock the no-abstract method in the abstract class :
the waterFilter field dependency annoys you because it is not valued, so an exception (NullPointerException) is raised during the test.
You really want to mock the no abstract method in the abstract class because you have already unitary tested this method and you don't want to duplicate this test.
1) If your the problem is the waterFilter field dependency.
you should mock the waterFilter field. To mock a field, it must be accessible and modifiable. In your case, it's not straight because the field is private.
So, you have two ways to access to it to be able to mock it :
change your design to give the possibility to set the field from a public method or in the constructor of MyDerivedClass.
use reflection to set the field (use an API or do it yourself because it's not hard).
You don't need to do verify operations with EasyMock. Just mock the result returned by waterFilter.filter(allComponents) such as :
waterFilterMock.filter(mockedComponents)
In this way, the mock returns the value you have chosen and in your JUnit assertion, you are able to do the correct assertion for your method under test.
Just for information, you could use Mockito instead of EasyMock. It's more flexible and it offers more readable operations.
For example, you could do it with Mockito :
Mockito.when(waterFilterMock.filter()).thenReturn(mockedComponents);
As you can see, it is more readable.
2) If you problem is that you really want to mock the no-abstract method in the abstract class because you have already unitary tested it
You should modify your design and use composition instead of inheritance. You would have not MyAbstractBaseClass any longer but simply a dependency between two classes (the one has a field of the other). In this way, you could mock the filterComponents() method in a natural way.
Expectations has to be set on mocked resources.
In your case i think you should inject a mocked instance of WaterFilter.
And your expectation,replay and verify should be set on waterFilter object instance.
You can refer to the example provided in given below link.
http://www.tutorialspoint.com/easymock/easymock_junit_integration.htm

How to handle 3rd Party Dependencies while Unit Testing

I am developing a plugin for a proprietary application.
The specification essentially is that I have functions with specified names. When installed, the parent application will call the functions in my plugin - passing in various parameters.
I want to unit test my plugin, but I don't have access to the source of the parent application. I can't instantiate the required parameters to test my function.
In this particular case, my parameter is an object with two data elements I access and a logging function that I access. Mocking up a sample wouldn't be too difficult, but I'm faced with a bit of a dilemma...
public PerSpecResponseObject myPluginFunction(ThirdPartyObject iUseThis){
...
}
I can't pass my own object into "myPluginFunction", I need something of the type ThirdPartyObject. If I define an interface, I don't have access to the ThirdPartyObject to specify that it implements the interface. I can't subclass ThirdPartyObject and use a generic parameter (<? extends ThirdPartyObject>), because my plugin is implementing an interface, so my parameter types are restricted. I looked into Mocking and while interesting, it didn't seem applicable for my situation.
What solutions exist for this situation?
It would indeed be best to be able to construct a real ThirdPartyObject.
Since you need to refer to this class, you have at least some 3rd party library on your class path that contains this class.
Are you sure there's no way to construct it, e.g. using a factory which is also in the library? Or by constructing another object and calling a method that will call your plugin with a ThirdPartyObject instance?
While this is sometimes called integration testing (since you're testing the integration with the main application), it can also be considured unit testing in the classical sense as long as the test doesn't e.g. put data in a database or does anything else that could potentially influence other tests.
If the above isn't possible, you may resort to mocking out ThirdPartyObject e.g. using Mockito. Try to make sure you your test code isn't coupled to your implementation any more than it needs to be. Some people think they need to mock out all dependencies of a class and then verify all method calls to those dependencies. They're introducing a lot of strong coupling and redundancy.
Concerning the 2 problems you mentioned, there are ways around both:
1) You say you can't make ThirdPartyObject implement an interface. That's true, but you can write an adapter that implements this interface and delegates to a ThirdPartyObject. Then the method called by the main application would simply delegate to the actual plugin method implementation that uses this interface.
Example (suppose ThirdPartyObject has a single method void thirdPartyMethodCall():
public interface InterfaceForThirdPartyObject {
void thirdPartyMethodCall();
}
public class ThirdPartyObjectAdapter implements InterfaceForThirdPartyObject {
private final ThirdPartyObject delegate;
public ThirdPartyObjectAdapter(ThirdPartyObject delegate) {
this.delegate = delegate;
}
public void thirdPartyMethodCall() {
delegate.thirdPartyMethodCall();
}
}
// your actual plugin implementation, not directly exposed to the main app
public class MyPlugin {
public PerSpecResponseObject myPluginFunction(InterfaceForThirdPartyObject iUseThis){
// this will contain your actual logic that you want to test
}
}
// this is the plugin as exposed to the main app
public class MyPluginAdapter implements PluginInterface {
private final MyPlugin delegate = new MyPlugin();
// this is called by the main application
public PerSpecResponseObject myPluginFunction(ThirdPartyObject iUseThis) {
delegate.myPluginFunction(new ThirdPartyObjectAdapter(iUseThis));
}
}
2) You say you can't subclass ThirdPartyObject because the plugin implements an interface that has a ThirdPartyObject as method argument instead of ? extends ThirdPartyObject. I don't see why that would be a problem: a method that takes a ThirdPartyObject as parameter will happily take instances of any subclass of ThirdPartyObject.
If you had access to the source of the parent application, you wouldn't be unit-testing, but integration-testing.
You can mock ThirdPartyObject. In fact, you have to mock ThirdPartyObject if what you want to do is unit-testing.
Just create a class with the same FQN as ThirdPartyObject, but keep it in your test folders so it doesn't get distributed.
This is the simplest I can think of.

JMockit : How to avoid code from superclasses' constructors

I need to test a class SportCar, which extends Car. The problem is that when I create my object under test
SportCar car = new SportCar();
it will also call the constructor from parent classes, for example, Car(). Those constructors do a lot of things, have a lot of environment dependencies and need a lot of configuration files I don't have, so I would like to create an instance of SportCar without calling inherited constructors.
The only solution I know for this is to create a Mockup for Car in which I overwrite constructor ($init) and static block ($clinit). But now my problem is, what happens if there are many classes in my hierarchy (SportCar extends Car that extends A that extends B that extends C...) and I want to avoid all the constructors? Should I create Mocks for ALL the previous classes?
class A extends B{
public A(){
// Plenty of things to avoid during tests
}
}
class Car extends A{
public Car(){
// Plenty of things to avoid during tests
}
}
class SportCar extends Car(){
}
If you are using jmockit, you do not have to do anything at all, as all the superclass constructors are mocked by default. In you unit test method you can just do:
public void testMockedStuff(#Mocked final ClassToBeMocked instance) {
to have evrything mocked away for you. You do not even have to create instances yourself.
Then you can modify annotation parameters to exclude methods you are teting from mocking.
Create a protected "do nothing" constructor in Car and have a protected constructor in SportsCar that calls it and call that from your test class, which can see that constructor btw - it has the privileges to do so.
This could be considered a slight stretch of the "design for test" pattern.
You can suppress the parent constructor using PowerMock
suppress(constructor(EvilParent.class));
However, if you have to do a lot of unit tests it may be worth figuring out how to fake out the enironment as well. Or convince other developers to let you do a little refactoring to allow service injection at least.

How to unit test abstract classes: extend with stubs?

I was wondering how to unit test abstract classes, and classes that extend abstract classes.
Should I test the abstract class by extending it, stubbing out the abstract methods, and then test all the concrete methods? Then only test the methods I override, and test the abstract methods in the unit tests for objects that extend my abstract class?
Should I have an abstract test case that can be used to test the methods of the abstract class, and extend this class in my test case for objects that extend the abstract class?
Note that my abstract class has some concrete methods.
There are two ways in which abstract base classes are used.
You are specializing your abstract object, but all clients will use the derived class through its base interface.
You are using an abstract base class to factor out duplication within objects in your design, and clients use the concrete implementations through their own interfaces.!
Solution For 1 - Strategy Pattern
If you have the first situation, then you actually have an interface defined by the virtual methods in the abstract class that your derived classes are implementing.
You should consider making this a real interface, changing your abstract class to be concrete, and take an instance of this interface in its constructor. Your derived classes then become implementations of this new interface.
This means you can now test your previously abstract class using a mock instance of the new interface, and each new implementation through the now public interface. Everything is simple and testable.
Solution For 2
If you have the second situation, then your abstract class is working as a helper class.
Take a look at the functionality it contains. See if any of it can be pushed onto the objects that are being manipulated to minimize this duplication. If you still have anything left, look at making it a helper class that your concrete implementation take in their constructor and remove their base class.
This again leads to concrete classes that are simple and easily testable.
As a Rule
Favor complex network of simple objects over a simple network of complex objects.
The key to extensible testable code is small building blocks and independent wiring.
Updated : How to handle mixtures of both?
It is possible to have a base class performing both of these roles... ie: it has a public interface, and has protected helper methods. If this is the case, then you can factor out the helper methods into one class (scenario2) and convert the inheritance tree into a strategy pattern.
If you find you have some methods your base class implements directly and other are virtual, then you can still convert the inheritance tree into a strategy pattern, but I would also take it as a good indicator that the responsibilities are not correctly aligned, and may need refactoring.
Update 2 : Abstract Classes as a stepping stone (2014/06/12)
I had a situation the other day where I used abstract, so I'd like to explore why.
We have a standard format for our configuration files. This particular tool has 3 configuration files all in that format. I wanted a strongly typed class for each setting file so, through dependency injection, a class could ask for the settings it cared about.
I implemented this by having an abstract base class that knows how to parse the settings files formats and derived classes that exposed those same methods, but encapsulated the location of the settings file.
I could have written a "SettingsFileParser" that the 3 classes wrapped, and then delegated through to the base class to expose the data access methods. I chose not to do this yet as it would lead to 3 derived classes with more delegation code in them than anything else.
However... as this code evolves and the consumers of each of these settings classes become clearer. Each settings users will ask for some settings and transform them in some way (as settings are text they may wrap them in objects of convert them to numbers etc.). As this happens I will start to extract this logic into data manipulation methods and push them back onto the strongly typed settings classes. This will lead to a higher level interface for each set of settings, that is eventually no longer aware it's dealing with 'settings'.
At this point the strongly typed settings classes will no longer need the "getter" methods that expose the underlying 'settings' implementation.
At that point I would no longer want their public interface to include the settings accessor methods; so I will change this class to encapsulate a settings parser class instead of derive from it.
The Abstract class is therefore: a way for me to avoid delegation code at the moment, and a marker in the code to remind me to change the design later. I may never get to it, so it may live a good while... only the code can tell.
I find this to be true with any rule... like "no static methods" or "no private methods". They indicate a smell in the code... and that's good. It keeps you looking for the abstraction that you have missed... and lets you carry on providing value to your customer in the mean time.
I imagine rules like this one defining a landscape, where maintainable code lives in the valleys. As you add new behaviour, it's like rain landing on your code. Initially you put it wherever it lands.. then you refactor to allow the forces of good design to push the behaviour around until it all ends up in the valleys.
Write a Mock object and use them just for testing. They usually are very very very minimal (inherit from the abstract class) and not more.Then, in your Unit Test you can call the abstract method you want to test.
You should test abstract class that contain some logic like all other classes you have.
What I do for abstract classes and interfaces is the following: I write a test, that uses the object as it is concrete. But the variable of type X (X is the abstract class) is not set in the test. This test-class is not added to the test-suite, but subclasses of it, that have a setup-method that set the variable to a concrete implementation of X. That way I don't duplicate the test-code. The subclasses of the not used test can add more test-methods if needed.
To make an unit test specifically on the abstract class, you should derive it for testing purpose, test base.method() results and intended behaviour when inheriting.
You test a method by calling it so test an abstract class by implementing it...
If your abstract class contains concrete functionality that has business value, then I will usually test it directly by creating a test double that stubs out the abstract data, or by using a mocking framework to do this for me. Which one I choose depends a lot on whether I need to write test-specific implementations of the abstract methods or not.
The most common scenario in which I need to do this is when I'm using the Template Method pattern, such as when I'm building some sort of extensible framework that will be used by a 3rd party. In this case, the abstract class is what defines the algorithm that I want to test, so it makes more sense to test the abstract base than a specific implementation.
However, I think it's important that these tests should focus on the concrete implementations of real business logic only; you shouldn't unit test implementation details of the abstract class because you'll end up with brittle tests.
one way is to write an abstract test case that corresponds to your abstract class, then write concrete test cases that subclass your abstract test case. do this for each concrete subclass of your original abstract class (i.e. your test case hierarchy mirrors your class hierarchy). see Test an interface in the junit recipies book: http://safari.informit.com/9781932394238/ch02lev1sec6. https://www.manning.com/books/junit-recipes or https://www.amazon.com/JUnit-Recipes-Practical-Methods-Programmer/dp/1932394230 if you don't have a safari account.
also see Testcase Superclass in xUnit patterns: http://xunitpatterns.com/Testcase%20Superclass.html
I would argue against "abstract" tests. I think a test is a concrete idea and doesn't have an abstraction. If you have common elements, put them in helper methods or classes for everyone to use.
As for testing an abstract test class, make sure you ask yourself what it is you're testing. There are several approaches, and you should find out what works in your scenario. Are you trying to test out a new method in your subclass? Then have your tests only interact with that method. Are you testing the methods in your base class? Then probably have a separate fixture only for that class, and test each method individually with as many tests as necessary.
This is the pattern I usually follow when setting up a harness for testing an abstract class:
public abstract class MyBase{
/*...*/
public abstract void VoidMethod(object param1);
public abstract object MethodWithReturn(object param1);
/*,,,*/
}
And the version I use under test:
public class MyBaseHarness : MyBase{
/*...*/
public Action<object> VoidMethodFunction;
public override void VoidMethod(object param1){
VoidMethodFunction(param1);
}
public Func<object, object> MethodWithReturnFunction;
public override object MethodWithReturn(object param1){
return MethodWihtReturnFunction(param1);
}
/*,,,*/
}
If the abstract methods are called when I don't expect it, the tests fail. When arranging the tests, I can easily stub out the abstract methods with lambdas that perform asserts, throw exceptions, return different values, etc.
If the concrete methods invoke any of the abstract methods that strategy won't work, and you'd want to test each child class behavior separately. Otherwise, extending it and stubbing the abstract methods as you've described should be fine, again provided the abstract class concrete methods are decoupled from child classes.
I suppose you could want to test the base functionality of an abstract class... But you'd probably be best off by extending the class without overriding any methods, and make minimum-effort mocking for the abstract methods.
One of the main motivations for using an abstract class is to enable polymorphism within your application -- i.e: you can substitute a different version at runtime. In fact, this is very much the same thing as using an interface except the abstract class provides some common plumbing, often referred to as a Template pattern.
From a unit testing perspective, there are two things to consider:
Interaction of your abstract class with it related classes. Using a mock testing framework is ideal for this scenario as it shows that your abstract class plays well with others.
Functionality of derived classes. If you have custom logic that you've written for your derived classes, you should test those classes in isolation.
edit: RhinoMocks is an awesome mock testing framework that can generate mock objects at runtime by dynamically deriving from your class. This approach can save you countless hours of hand-coding derived classes.
First if abstract class contained some concrete method i think you should do this considered this example
public abstract class A
{
public boolean method 1
{
// concrete method which we have to test.
}
}
class B extends class A
{
#override
public boolean method 1
{
// override same method as above.
}
}
class Test_A
{
private static B b; // reference object of the class B
#Before
public void init()
{
b = new B ();
}
#Test
public void Test_method 1
{
b.method 1; // use some assertion statements.
}
}
If an abstract class is appropriate for your implementation, test (as suggested above) a derived concrete class. Your assumptions are correct.
To avoid future confusion, be aware that this concrete test class is not a mock, but a fake.
In strict terms, a mock is defined by the following characteristics:
A mock is used in place of each and every dependency of the subject class being tested.
A mock is a pseudo-implementation of an interface (you may recall that as a general rule, dependencies should be declared as interfaces; testability is one primary reason for this)
Behaviors of the mock's interface members -- whether methods or properties
-- are supplied at test-time (again, by use of a mocking framework). This way, you avoid coupling of the implementation being tested with the implementation of its dependencies (which should all have their own discrete tests).
Following #patrick-desjardins answer, I implemented abstract and it's implementation class along with #Test as follows:
Abstract class - ABC.java
import java.util.ArrayList;
import java.util.List;
public abstract class ABC {
abstract String sayHello();
public List<String> getList() {
final List<String> defaultList = new ArrayList<>();
defaultList.add("abstract class");
return defaultList;
}
}
As Abstract classes cannot be instantiated, but they can be subclassed, concrete class DEF.java, is as follows:
public class DEF extends ABC {
#Override
public String sayHello() {
return "Hello!";
}
}
#Test class to test both abstract as well as non-abstract method:
import org.junit.Before;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.contains;
import java.util.Collection;
import java.util.List;
import static org.hamcrest.Matchers.equalTo;
import org.junit.Test;
public class DEFTest {
private DEF def;
#Before
public void setup() {
def = new DEF();
}
#Test
public void add(){
String result = def.sayHello();
assertThat(result, is(equalTo("Hello!")));
}
#Test
public void getList(){
List<String> result = def.getList();
assertThat((Collection<String>) result, is(not(empty())));
assertThat(result, contains("abstract class"));
}
}

Categories