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);
}
Related
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.
Consider the following code:
public interface MyClass {
public final String getMyObject1();
public final String getMyObject2();
}
public class MyClass1 implements MyClass {
private String myObject1;
private String myObject2;
public MyClass1(String myObject1, String myObject2) {
this.myObject1 = myObject1;
this.myObject2 = myObject2;
}
public String getMyObject1() {
return myObject1;
}
public String getMyObject2() {
return myObject2;
}
}
public interface MyClass2 extends MyClass {
public static MyClass2 newInstance(String myObject1, String myObject2) {
return new MyClass2() {
public String getMyObject1() {
return myObject1;
}
public String getMyObject2() {
return myObject2;
}
};
}
}
And I use them like
public static void func(MyClass m) {
m.getMyObject1();
m.getMyObject2();
}
func(new MyClass1(o1, o2));
func(MyClass2.newInstance(o1, o2));
I wonder how they differ and if I only need to read from the values (i.e. to use MyClass as a "struct" to pass values), using the anonymous class can it be a simpler approach?
Otherwise, what are the draw backs?
One core rule of programming: try to not surprise your readers.
Your approach here to use a static class within an interface as "factory" method is very surprising (and believe me: I have seen a lot of Java code).
If at all, the more "common" way of handling such things: create a static class with a slightly similar name, you know, like there is java.lang.Object and java.lang.Objects that carries some useful static helper methods.
And beyond that, there is already a class in Java that helps with arbitrary numbers of "named" values; and that is called a Map!
Finally: there are some good arguments for "DTO"s (data transfer objects) but esp. for "beginners", you should rather look into "real" OO designs; based on the SOLID principles. In that sense: design real classes that exactly model your problem domain; and that provide helpful abstractions. A struct with an arbitrary number of members ... doesn't fall into either category.
The problem here is not the code necessarily but the design. I would be interested to know the real world use case you are trying to design here.
Surely there are limitations in the second approach like you cannot update the value of your objects at all once your class is created as you just have a way to get the value of the passed objects back.
Coming back to Design:
An interface is supposed to be an action which your class can perform if it implements that interface. In your case you are trying to return the value of two instance variables using the two methods in your interface which is a kind of action but it ignores the basic principle of encapsulation.
If your class defines/owns those instance variables it should have the getters and setters for that. You should not require an interface to do that. So ideally your interface should not be required. Any other class which uses MyClass1 object should directly use the getters and setters of the MyClass1.
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.
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.
What would be the practical side of the ability to define a class within an interface in Java:
interface IFoo
{
class Bar
{
void foobar ()
{
System.out.println("foobaring...");
}
}
}
I can think of another usage than those linked by Eric P: defining a default/no-op implementation of the interface.
./alex
interface IEmployee
{
void workHard ();
void procrastinate ();
class DefaultEmployee implements IEmployee
{
void workHard () { procrastinate(); };
void procrastinate () {};
}
}
Yet another sample — implementation of Null Object Pattern:
interface IFoo
{
void doFoo();
IFoo NULL_FOO = new NullFoo();
final class NullFoo implements IFoo
{
public void doFoo () {};
private NullFoo () {};
}
}
...
IFoo foo = IFoo.NULL_FOO;
...
bar.addFooListener (foo);
...
I think this page explains one example pretty well. You would use it to tightly bind a certain type to an interface.
Shamelessly ripped off from the above link:
interface employee{
class Role{
public String rolename;
public int roleId;
}
Role getRole();
// other methods
}
In the above interface you are binding the Role type strongly to the employee interface(employee.Role).
One use (for better or worse) would be as a workaround for the fact that Java doesn't support static methods in interfaces.
interface Foo {
int[] getData();
class _ {
static int sum(Foo foo) {
int sum = 0;
for(int i: foo.getData()) {
sum += i;
}
return sum;
}
}
}
Then you'd call it with:
int sum = Foo._.sum(myFoo);
I can say without hesitation that I've never done that. I can't think of a reason why you would either. Classes nested within classes? Sure, lots of reasons to do that. In those cases I tend to consider those inner classes to be an implementation detail. Obviously an interface has no implementation details.
One place this idiom is used heavily is in XMLBeans. The purpose of that project is to take an XML Schema and generate a set of Java classes that you can use bidirectionally to work with XML documents corresponding to the schema. So, it lets you parse XML into xml beans or create the xml beans and output to xml.
In general, most of the xml schema types are mapped to a Java interface. That interface has within it a Factory that is used to generate instances of that interface in the default implementation:
public interface Foo extends XmlObject {
public boolean getBar();
public boolean isSetBar();
public void setBar(boolean bar);
public static final SchemaType type = ...
public static final class Factory {
public static Foo newInstance() {
return (Foo)XmlBeans.getContextTypeLoader().newInstance(Foo.type, null);
}
// other factory and parsing methods
}
}
When I first encountered this it seemed wrong to bind all this implementation gunk into the interface definition. However, I actually grew to like it as it let everything get defined in terms of interfaces but have a uniform way to get instances of the interface (as opposed to having another external factory / builder class).
I picked it up for classes where this made sense (particularly those where I had a great deal of control over the interface/impls) and found it to be fairly clean.
I guess you could define a class that is used as the return type or parameter type for methods within the interface. Doesn't seem particularly useful. You might as well just define the class separately. The only possible advantage is that it declares the class as "belonging" to the interface in some sense.
Google Web Toolkit uses such classes to bind 'normal' interface to asynchronous call interface:
public interface LoginService extends RemoteService {
/**
* Utility/Convenience class.
* Use LoginService.App.getInstance() to access static instance of LoginServiceAsync
*/
class App {
public static synchronized LoginServiceAsync getInstance() {
...
}
}
}
With a static class inside an interface you have the possibility to shorten a common programming fragment: Checking if an object is an instance of an interface, and if so calling a method of this interface. Look at this example:
public interface Printable {
void print();
public static class Caller {
public static void print(Object mightBePrintable) {
if (mightBePrintable instanceof Printable) {
((Printable) mightBePrintable).print();
}
}
}
}
Now instead of doing this:
void genericPrintMethod(Object obj) {
if (obj instanceof Printable) {
((Printable) obj).print();
}
}
You can write:
void genericPrintMethod(Object obj) {
Printable.Caller.print(obj);
}
Doing this seems to have "Bad design decision" written all over it.
I would urge caution whenever it seems like a good idea to create a non-private nested class. You are almost certainly better off going straight for an outer class. But if you are going to create a public nested class, it doesn't seem any more strange to put it in an interface than a class. The abstractness of the outer class is not necessarily related to the abstractness of a nested class.
This approach can be used to define many classes in the same file. This has worked well for me in the past where I have many simple implementations of an interface. However, if I were to do this again, I would use an enum which implements an interface which would have been a more elegant solution.