Deal with Final Class With Static Method - java

I have a method, I want to test. In there I call a static method of a final Hybris-class (Config.getParameter("aString")). I want to mock it, but I found out, you can't do that with Mockito. So what would be a good way to approach this? The thing is, I am thinking about refactoring. But I can't change the Config-class, since it is from Hybris.
How can I change my class I want to test, so that I can influence the Config.getParameter("aString") call?
Thanks!

There are two ways to do it:
1.Refactor your code and introduce ConfigWrapper (for example) interface:
public interface ConfigWrapper {
public String getParameter(String parameter);
public class ConfigWrapperImpl implements ConfigWrapper{
public String getParameter(String parameter){
return Config.getParameter(parameter);
}
}
Then you should refactor your code and replace Config.* usages by injecting ConfigWrapper. And when you write a test you can easily mock ConfigWrapper with mockito (cause you are using non-static method)
The second way is to use PowerMock instead of mockito:
PowerMock.mockStatic(ClassThatContainsStaticMethod.class)
for more info u can see: https://github.com/jayway/powermock/wiki/MockStatic

One solution is to create an interface whose method (or methods) match what you expect from that Config class. Then you can do the following:
create an implementation which uses that Config in production;
create a mock for your tests.
A simplified example using Java 8:
// The interface
public interface MyInterface
{
String getParameter(String paramName);
}
// Class using the interface
public final class MyClass
{
private final MyInterface intf;
// For testing...
public MyClass(final MyInterface intf)
{
this.intf = Objects.requireNonNull(intf);
}
// In production...
public MyClass()
{
this(Config::getParameter);
}
// etc
}
// Test class
#Test
public void whatever()
{
final MyInterface intf = mock(MyInterface.class);
// set up the mock, then...
final MyClass myClass = new MyClass(intf);
// test myClass
}

You could use besides Mockito, a tool call PowerMock which can be helpful in your use case.

Related

How to call a method inside an interface implementation on the interface level

I have an interface with 1 method signature:
public interface UrlProvider {
String getUrl();
}
There are 2 implementations of this interface, and one of them has a public method whose signature is not in the interface because it only makes sense to be inside the implementation:
public class UrlProviderImpl implements UrlProvider {
#Override
public String getUrl() {
//implementation
}
public String getUrlAndAppend() {
//implementation
}
}
There's a third class that's going to have a UrlProvider field and Spring is going to handle the dependency injection and instantiating the correct beans. Is it possible to call getUrlAndAppend() on the interface level without explicitly instantiating the implementation?
This is what I am trying to achieve:
public class ThirdClass {
private final UrlProvider urlProvider;
public void myMethod() {
urlProvider.getUrlAndAppend();
}
}
In terms of design, how this is usually handled?
If you know when you want the extra functionality in some places, consider making a new interface, or injecting the specific implementation in the places you know you need the extra functionality. Without reflection (which is a terrible idea; don't do it), you can't access that method from the interface.
public interface AppendingUrlProvider extends UrlProvider {
String getUrlAndAppend();
}
public class AppendingUrlProviderImpl implements AppendingUrlProvider {
#Override
public String getUrl() {
// implementation
}
#Override
public String getUrlAndAppend() {
// implementation
}
}
////
// Or modify your existing ThirdClass
////
public class ThirdClass {
// inject the implementation, not the interface
private final UrlProviderImpl urlProvider;
public void myMethod() {
urlProvider.getUrlAndAppend();
}
}
Solutions aside, the first thing you should really do is figure out exactly why you need this extra public method on just one of the implementations. Is this something that callers should be doing instead of the implementation? Should this be on the interface? Is this only needed for testing? Only you can answer this, but it's worth taking a step back to make sure you've set up your codebase for success and longterm maintainability.
Did you try your own code?
You can't call a method that belongs to an instance of a class, if you do not instantiate that class.
In your example, if you call myMethod without instantiating UrlProvider you will get a NullPtrException.
If you want to have access to getUrlAndAppend from the interface, you will need to declare that method as "default" in the interface itself or as Static from the implementation (and that way you do not need to instantiate it to call the method), but I'm having trouble to understand what you want to achieve from this.

Android Unit Testing : How do I test this?

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());
}

Testing wrapper class

I would like to test a class that is used as a wrapper that provides abstraction for the classes underneath.
That means that I need to create some objects inside that class, that is, I don't pass collaborators through constructor or some method.
For example, here's a wrapper class:
public class Abstraction {
private ComplexClass complex;
public class Abstraction(some parameters) {
complex = new Complex(parameters);
}
}
To be able to test this class I had an idea to create a method that will return an object of Complex class, like this:
public class Abstraction {
private ComplexClass complex;
public class Abstraction(parameters) {
complex = createComplex(parameters);
}
protected createComplex ComplexClass(parameters) {
return new ComplexClass(parameters);
}
}
The thing is, I cannot use Mockito to mock collaborators created inside constructor of class that I'm testing. How to overcome this?
My idea was to spy the SUT so that createComplex returns mock object, but I cannot do that because SUT needs to be created first. It's kind of a dead lock.
My final goal is to test whether some methods of collaborator classes were called.
What is the business advantage of testing this class? It doesn't implement an algorithm and it doesn't make a decision. As you say, it is only a wrapper.
You say that you want to test if certain methods are called but how does that help anybody? Surely a test that confirms that the methods were called in some situations and not others, in other words a test of the business logic, would be much more useful. The risk here is that you will end up with a complex test that is difficult to maintain and introduces inertia that will make future re-factoring much more difficult and expensive. What is the reward you are hoping foir that will make that risk worthwhile?
You could do it with a reasonably simple anonymous inner class in your test case
ComplexClass mock = Mockito.mock(ComplexClass.class);
Abstraction abstraction = new Abstraction("foo") {
#Override
protected ComplexClass createComplex(parameters) {
return mock;
}
};
assertTrue("bar", abstraction.doStuff());
You could implement a factory for your ComplexClass which you set on your Abstraction:
public class ComplexClassFactory {
public ComplexClass create(parameters) {
return new ComplexClass(parameters);
}
}
public class Abstraction {
private ComplexClassFactory complexClassFactory;
public void setComplexClassFactory(ComplexClassFactory complexClassFactory) {
this.complexClassFactory = complexClassFactory;
}
private ComplexClass complex;
public class Abstraction(parameters) {
complex = complexClassFactory.create(parameters);
}
}
One possibility is to extract an interface for the ComplexClass class (which I named Complex) and provide an alternate constructor used only for testing purposes to inject an instance of the newly created Complex interface:
public class Abstraction {
private Complex complex;
public Abstraction(String parameters) {
this.complex = new ComplexClass(parameters);
}
Abstraction(Complex complex) {
this.complex = complex;
}
public class ComplexClass implements Complex {
private final String parameters;
public ComplexClass(String parameters) {
this.parameters = parameters;
}
}
interface Complex {
}
}
This way you can create a mock for the Complex interface, use the constructor which receives a Complex instance and test the Abstraction class independently:
#Test
public void testAbstraction() {
Complex mock = Mockito.mock(Complex.class);
Abstraction abstraction = new Abstraction(mock);
}

How to test private method without using PowerMock (Use case: object creation)?

I have encapsulated the object creation into new method as specified in https://code.google.com/p/mockito/wiki/MockingObjectCreation [Pattern 1: using one-line methods for object creation]
I have used private before makeFoo method. Which is making my work harder.
Wasn't private necessary for makeFoo method?
If so how people handled it?
If you make the method protected you can override it in a test double of your SUT. This way you can make the method return some mock, spy or other type of test double.
If at all possible, however, I'd recommend you to inject the dependency class in the constructor. It saves you some headache and boiler plate code. There are cases where a protected factory method is a "better" solution though, just something to keep in mind.
EDIT: Example of constructor injection:
Going from this
public class MyClass
{
private SomeDependency someDependency;
public MyClass()
{
this.someDependency = new SomeDependency(new A(), new B());
}
public void doWork()
{
_someDependency.doSomething();
}
}
To this
public class MyClass
{
private SomeDependency someDependency;
public MyClass(SomeDependency someDependency)
{
this.someDependency = someDependency;
}
public void doWork()
{
this.someDependency.doSomething();
}
}
This allows you to inject your class with a test double directly rather than inheriting it and overriding some factory method.

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() ;
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.

Categories

Resources