Mock interfaces used by a concrete class with mockito - java

I essentially have a main class that uses interfaces to call other classes which contain members. I am supposed to mock the interfaces that this (concrete) main class uses to call the other classes. The purpose of this is to create a mocked getMember() method for these other classes that would be cumbersome to implement. We only need to ensure, for now, that the main class behaves as expected, given certain return values from the getMember() method.
The only way I see this being possible right now is by passing mock instances of the classes that implement those interfaces.
I'm very sorry if this seems like a stupid question, but I just cannot find an answer to my question by reading this assignment, documentation or via search engines.

Try this:
AnInterface anInterfaceMock = Mockito.mock(AnInterface.class);
//Set your properties here if you want return an specific object.
Member member = new Member();
Mockito.when(anInterfaceMock.getMember()).thenReturn(member);
YourMainClass yourMain = new YourMainClass();
yourMain.setAnInterfaceMock(anInterfaceMock);
yourMain.testMethod(); // call the method you wan to test. This method internal implementation is supposed to call anInterfaceMock.getMember()
Mockito.verify(anInterfaceMock).getMember();
UPDATE:
After the info about the main class not having a way to force the chose interface to mock, it seems like a work to PowerMockito. But posting the code of your main class would help a lot.

Is it your main class that creates the instances of its dependencies (that implement those interfaces that you mentioned)?
If possible you'd better change the main class to follow the Dependency Injection pattern. Then you'll supply our main class with its dependencies via constructor or via setters. Those dependencies can be mocks for testing or the true implementations in the production code.
Modifying the guilhermerama's example a bit.
YourMainClass yourMain = new YourMainClass(anInterfaceMock);

Related

How to mock new instance where it return interface reference

I have a scenario like this
MyInterface myObject = new MyInterfaceImplementedClass();
myObject.get(...)
I want to mock the MyInterfaceImplementedClass, I tried like below
private MyInterface mockMyObject
private MyInterfaceImplementedClass mockMyClassObject
// the below compilation error
whenNew(MyInterfaceImplementedClass.class).withNoArguments().thenReturn(mockMyObject);
// no compilation error but not giving mocking instance at runtime
whenNew(MyInterfaceImplementedClass.class).withNoArguments().thenReturn(mockMyClassObject);
Please help me on this
Solved in the comments:
after adding my test class in side #PrepareForTest, it works as expected
In short, Mockito writes a generated subclass for the class you're trying to mock, which allows it to intercept the behavior of overridable methods (i.e. non-final instance methods). This handles all interfaces and most abstract and concrete classes. However, if you're trying to mock the behavior of final or static methods, including constructors, there's nothing Mockito can do1: the consuming class contains a reference to the exact real implementation without a lookup to the virtual method table. The only way out is to rewrite and replace the bytecode of an existing class, which is exactly what PowerMock does.
It can often just overwrite the class you're trying to mock, but in certain circumstances you need to list the class under test or the test class itself.
Consequently, almost all tests that exercise PowerMock's features require a #PrepareForTest, as well as a #RunWith statement that ensures that the test class uses PowerMock's classloader to enable that rewriting.
1 since Mockito 2.1, Mockito can use instrumented classloaders to do some of the things that were previously only available in PowerMock.

Is the Method object equivalent to the Command object in the Command design pattern?

I've just discovered about the existence of the Method class in Java.
Is an instance of this class equivalent to an instance of a Command class in the context of the Command design pattern?
If not, what are this class' practical uses?
Is an instance of this class equivalent to an instance of a Command class in the context of the Command design pattern?
No, absolutely not: Method class is part of reflection feature of Java. Command pattern, on the other hand, is language-agnostic, so it can be implemented in any language, including ones that lack reflection capabilities.
The practical use of the Method class is to access methods of classes to which you do not have access at compile time. You can load a class by name, grab its method object - also by name, and perform an invocation.
With this said, it does not mean that you couldn't implement something that behaves like the command pattern using reflection. In fact, you could make your implementation more flexible by eliminating compile-time dependency on your code. For example, you could build a system that take plugins, and requires that plugin classes implement a particular method. Rather than shipping to plugin writers an interface with the signature of the method, you could tell them that as long as their class implements the method that you need, the plugin is going to be accepted. At runtime you would be able to discover the proper method through reflection, and call user code without compile-time dependencies on either side.
This class, as well as the class Field, class Class, are all part of reflection API. This API is used to provide access to object in an indirect way.
The first idea behind reflection was to allow an object to describe itself. For instance an IDE could display all properties of an object for debugging, RAID development and so on.
If reflection is still used that way, it's also used today to discover dynamically the structure of an object or a class and "act on" it without explicitly knowing it : to change the values of its fields or invoke one its methods.
For instance, if you know class A, you can invoke the method m() of A this way :
A a = new A();
a.m();
With reflection, without knowing class A explicitly, you could :
Object a = A.getDeclaredConstructors()[0].newInstance();
Method m = a.getClass().getMethod("m");
m.invoke(a, null);
In the second case, you can imagine a more generic mechanism where you discover methods or fields and invoke them or change their values without knowing them in advance.
So, to answer directly your question, it has nothing to do with the Command design pattern.

How to test anonymous nested class in java?

I need check with junit that method of nested anonymous class invoked. But this class is private. Does there exist a way to test it without changing visiblity and logic of work? It may be that a common way exists to resolve similar problems?
The fact that the class is private or anonymous means that the implementation details are private. In general, your tests should not be depending upon implementation details, but should be testing behaviour, not the specific implementation.
The only way is to test the method that creates the object of the anonymous inner class, or to make it non-anonymous and non-private. (I've seen a fair amount of code that makes it default-visibility and uses a #VisibleForTesting annotation.)
You should not test that private class directly.
Most likely it's just a small class used as a util or it implements some broad, public interface.
In the first case just test class that wraps up the private class, and don't worry about private one at all. You can treat it as an implementation detail.
In second case just test that class against it public interface.
If I'm wrong about your code, then my advise would be to change design a bit, move wrapper class into separate package, extract private class to package level and test it directly.
Last way would be to mark it as #VisibleForTesting (annotation from Guava library) and raise visibility to package private (default).
I quite agree with Matthew Farwell when he says:
In general, your tests should not be depending upon implementation
details, but should be testing behaviour, not the specific
implementation.
However, tests call out for good design. If you really feel you should test that class directly, then that's a hint that that class should be a normal public class (and not an inner anonymous).

Unit Testing with JUnit

As i understand it, the correct way to test private methods is via reflection? So if we test a method via reflection, we need to make an instance of the class, get the method, invoke it and so on. However, what do we do if the class that we create uses data from other objects that will return null / be null without the correct previously made objects.
Thanks
I personally think you should avoid writing tests on private methods. Using reflection to me is a design smell - you should ideally write tests only against the exposed public interface of your class.
If you feel the need to test a private method, then this suggests to me that you should do one of the following:
Recognise that the method really should be part of the public interface and make it public
Write a test against some existing public methods of the class that indirectly test the private method
Write a new public method that exposes the behaviour you wish to test
Refactor the behaviour out into another class which you can test (thanks Tom for the extra idea!)
As i understand it, the correct way to test private methods is via
reflection?
It's the only way (if you're only testing the private method, and not some other public method that calls the private method), as you cannot access the private methods from outside of the class (except with reflection). I don't usually write separate tests for private-methods, but it can be useful.
what do we do if the class that we create uses data from other objects
that will return null / be null without the correct previously made
objects.
In unit-tests, you "mock" the outside dependencies, either using a mocking-library, such as Mockito or some other, or write anonymous or separate mocking classes implementing the interface of the dependency. The idea is that you define some exact behavior for the outside dependencies, so their behavior won't affect the testing of the actual class. If the fields holding the references are private, you need to use reflection to inject the objects into them.
In integration-testing, you use the actual implementations of the outside dependencies.
You can use an existing instance of the class (say, the instance on which you've already tested the public methods).
Now just invoke the private method (found through reflection) of that instance, which, presumably, must have all the 'previously made' objects.

Run JUnit test againsts arbitrary loaded class

As part of a larger project, I am attempting to achieve something that I'm not sure is possible, so am eager to see if anyone has any suggestions!
The overall system:
As a whole, my system should be able to be provided with a JUnit test class, that matches some provided interface. Classes will be then given that do not implement this interface, but need to be checked to see if they would be able to (a.k.a. if they implement all necessary methods). If so, some transformation should take place such that the JUnit test class can be run against it.
So far I have implemented:
- A package that loads other classes given a path and name, using URLClassLoader
- A package that runs a JUnit test case and returns the results, using JUnitCore
The problem:
1. At first, how could I run the JUnit test against a class that does implement the interface when the test is designed to match the interface? How do I (at runtime) dictate that the instance being tested by the interface is the loaded class?
Is it possible to then extend this, such that I could i) verify that it does match the interface (I assume using Reflection to check for corresponding methods?) and then ii) modify that class such that it can be tested using the JUnit test class?
Thanks for any advice that might help towards part of this problem. I appreciate my description may be lacking, so please comment if you have any extra information that would help you give any answer!
You can do everything you want with the reflection API. It sounds like you should start with the tutorial, and then come back here for specific questions. Given a Class object you can check if it implements a given interface, create an instance of it, and then treat it like any other class.
Edit: I don't think I got that from your question, but in that case you are looking for the Proxy part of the reflection API.
how could I run the JUnit test against
a class that does implement the
interface when the test is designed to
match the interface
Since you have the class you can use the isAssignableFrom method offered by the class such that
Class loadedJunitClass = clazz;
MyInterface impl = null;
if(MyInterface.class.isAssignableFrom(loadedJunitClass )){
impl = (MyInterface) loadedJunitClass.newInstance();
}
For the second question, you can check each method and see 1. If there exists a method with the same method name as defined in the interface, 2. If the method return type is the same from the interface and 3. If the method parameter types and length are the same. Of course 2 and 3 can be tricky to get right.
At that point I would just create an instance of that interface (anonymous or a private class), create a newInstance of that matching class. And invoke the methods through reflection within the interface's methods.
Now that is how you can get it done with reflection. I am not advicating reflection as you can imagine :)
For the first part of your question; if you have the loaded Class instance for the class you want to test you can construct one with newInstance() if it has a default constructor, or via the getConstructor methods if you need to pass parameters. You should be able to get this Class instance from the class loader.
For the second part. You should be able to check the public methods via getMethods() (again on the Class instance) then look through the returned array for the methods you want. There are methods on the Method class that will return information about parameters, exceptions and return type to verify they are what you require.
However, I am pretty certain it is not possible to modify the class at runtime to add the interface. It might be possible by modifying the byte code, but I don't know about that.
An alternative would be to write your test to call all method via reflection, then it doesn't matter what the type of the object is just that it has the right methods (which you've already checked).
If you want to make arbitrary class to implement given interface at runtime if its public API matches the interface, you have several options in Java. Creating java.lang.Proxy to bridge the target class, exposing YourInterface is the easiest way.
YourInterface i = (YourInterface) Proxy.newProxyInstance(
this.getClass().getClassLoader(),
new Class[]{YourInterface.class},
new InvocationHandler() {
#Override
public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
//run method on your target class here using reflection
}
});
You can also use mixins in AspectJ or subclass your target class using CGLIB and add interface at runtime. But the proxy approach is not that hard-core to implement.

Categories

Resources