So my class under test has code that looks braodly like this
public void doSomething(int param)
{
Report report = new Report()
...do some calculations
report.someMethod(someData)
}
my intention was to extract the construction of report into a protected method and override it to use a mock object that I could then test to ensure that someMethod had been called with the right data.
So far so good. But Report isnt under my control, and to mkae things worse it uses JNI to load a library at runtime.
If I do
Report report = EasyMock.createMock(Report.class)
then EasyMock attempts to use reflection to find out the class members, but this causes an attempt to load the JNI library, which fails (the JNI libraries are only available on UNIX).
Im considering two things: a) Introduce a ReportWrapper interface with two implementations, one of which will delegate calls to an real Report (so basically a Proxy), and a second which will basically use a mock object. or b) instead of calling someMethod, call a protected method which will in turn call someMethod that I can override in a testing subclass.
Either way it seems nasty. Any better ways?
If there's no interface to Report class, then your suggested wrapper is the correct approach.
The book "Refactoring: Improving the Design of Existing Code" has a chapter about extracting interfaces from badly designed classes.
If you're using some DI framework (e.g. SpringFramework) you can easily replace this object with some ObjectFactory to create the correct implementation (mock vs. real one).
With EasyMock, you would have to resort to some form of refactoring. The only way to avoid it would be to use a mocking tool which can mock internally created objects. With JMockit (a tool I develop), the test could be written like this:
public void testDoSomething(final Report mockedReport)
{
// create "someData"
objectUnderTest.doSomething(123);
new Verifications() {{ mockedReport.someMethod(someData); }};
}
Related
I need to write a piece of code which checks a string coming back from a method call. The problem is, that I have no information or implementation about this method apart from its interface as below:
package com.company.name.library;
public interface FooService {
String getBar(String fooBar) throws NotKnownBarException, NotKnownFooException;
}
In a completely separate package I want to write some code that uses this method. (Essentially I need this code to compile, not necessarily run)
Since I don't have the implementation, I can't instantiate the object on which to invoke the method call. Is it even possible to make this compile with such limited information? Or is there something that has to be done such that I can make the code compile and at runtime some kind of injection is performed so that the correct method call can be made when there will be an implementation available.
All you should need to use this functionality is the interface definition. At some point the client for your piece of code has to pass in an object which implements this interface which you then use.
That you don't have to depend on a particular implementation is generally a good thing from a decoupling point of view. You do need one for running your code and unit testing it of course. For that you may need to create a mock implementation of your own.
Pseudo-Java-code as below (Disclaimer: Java is not my main language)
package com.company.name.yourpackage
class UsesFoo {
// constructor
UsesFoo(FooService giveMeAnImplementationPlease)
{
}
String DoSomethingWithFoo()
{
return anImplementationIWasGiven.getBar()
}
// state
FooService anImplementationIWasGiven;
}
Depending on what the library is for it might be intended that you create your own implementation. In which case you can turn the example around and assume the library has classes like UsesFoo which need you to provide the implementation.
If the usage isn't clear then you should complain to whoever provided the library without sufficient documentation. If that is not possible for some reason you may also consider adding to it yourself so that others don't have to suffer.
Perhaps I have completely fallen short in my search, but I cannot locate any documentation or discussions related to how to write a unit test for a Java class/method that in turn calls other non-private methods. Seemingly, Mockito takes the position that there is perhaps something wrong with the design (not truly OO) if a spy has to be used in order to test a method where mocking internal method calls is necessary. I'm not certain this is always true. But using a spy seems to be the only way to accomplish this. For example, why could you not have a "wrapper" style method that in turn relies on other methods for primitive functionality but additionally provides functionality, error handling, logging, or different branches dependent on results of the other methods, etc.?
So my question is two-fold:
Is it poorly designed and implemented code to have a method that internally calls other methods?
What is the best practice and/or approach in writing a unit test for such a method (assuming it is itself a good idea) if one has chosen Mockito as their mocking framework?
This might be a difficult request, but I would prefer for those who decide to answer to not merely re-publish the Mockito verbiage and/or stance on spies as I already am aware of that approach and ideology. Also, I've used Powermockito as well. To me, the issue here is that Mockito developed this framework where additional workarounds had to be created to support this need. So I suppose the question I am wanting an answer to is if spies are "bad", and Powermockito were not available, how is one supposed to unit test a method that calls other non-private methods?
Is it poorly designed and implemented code to have a method that internally calls other methods?
Not really. But I'd say that, in this situation, the method that calls the others should be tested as if the others where not already tested separately.
That is, it protects you from situations where your public methods stops calling the other ones without you noticing it.
Yes, it makes for (sometimes) a lot of test code. I believe that this is the point: the pain in writing the tests is a good clue that you might want to consider extracting those sub-methods into a separate class.
If I can live with those tests, then I consider that the sub-methods are not to be extracted yet.
What is the best practice and/or approach in writing a unit test for such a method (assuming it is itself a good idea) if one has chosen Mockito as their mocking framework?
I'd do something like that:
public class Blah {
public int publicMethod() {
return innerMethod();
}
int innerMethod() {
return 0;
}
}
public class BlahTest {
#Test
public void blah() throws Exception {
Blah spy = spy(new Blah());
doReturn(1).when(spy).innerMethod();
assertThat(spy.publicMethod()).isEqualTo(1);
}
}
To me, this question relates strongly to the concept of cohesion.
My answer would be:
It is ok to have methods (public) that call other methods (private) in a class, in fact very often that is what I think of as good code. There is a caveat to this however in that your class should still be strongly cohesive. To me that means the 'state' of your class should be well defined, and the methods (think behaviours) of your class should be involved in changing your classes state in predictable ways.
Is this the case with what you are trying to test? If not, you may be looking at one class when you should be looking at two (or more).
What are the state variables of the class you're trying to test?
You might find that after considering the answers to these types of questions, your code becomes much easier to test in the way you think it should be.
If you really need (or want) to avoid calling the lower-level methods again, you can stub them out instead of mocking them. For example, if method A calls B and C, you can do this:
MyClass classUnderTest = new MyClass() {
#Override
public boolean B() {return true;}
#Override
public int C() {return 0;}
};
doOtherCommonSetUp(classUnderTest);
String result = classUnderTest.A("whatever");
assertEquals("whatIWant", result);
I've used this quite a quite a bit with legacy code where extensive refactoring could easily lead to the software version of shipwright's disease: Isolate something difficult to test into a small method, and then stub that out.
But if the methods being called are fairly innocuous and don't requiring mocking, I just let them be called again without worrying that I am covering every path within them.
The real question should be:
What do I really want to test?
And actually the answer should be:
The behaviour of my object in response to outside changes
That is, depending on the way one can interact with your object, you want to test every possible single scenario in a single test. This way, you can make sure that your class reacts according to your expectations depending on the scenario you're providing your test with.
Is it poorly designed and implemented code to have a method that internally calls other methods?
Not really, and really not! These so called private methods that are called from public members are namely helper methods. It is totally correct to have helper methods!
Helper methods are there to help break some more complex behaviours into smaller pieces of reusable code from within the class itself. Only it knows how it should behave and return the state accordingly through the public members of your class.
It is unrare to see a class with helper methods and normally they are necessary to adopt an internal behaviour for which the class shouldn't react from the outside world.
What is the best practice and/or approach in writing a unit test for such a method (assuming it is itself a good idea) if one has chosen Mockito as their mocking framework?
In my humble opinion, you don't test those methods. They get tested when the public members are tested through the state that you expect out of your object upon a public member call. For example, using the MVP pattern, if you want to test user authentication, you shall not test every private methods, since private methods might as well call other public methods from an object on which depend the object under test and so forth. Instead, testing your view:
#TestFixture
public class TestView {
#Test
public void test() {
// arrange
string expected = "Invalid login or password";
string login = "SomeLogin";
string password = "SomePassword";
// act
viewUnderTest.Connect(login, password);
string actual = viewUnderTest.getErrorMessage;
// assert
assertEqual(expected, actual);
}
}
This test method describes the expected behaviour of your view once the, let's say, connectButton is clicked. If the ErrorMessage property doesn't contain the expected value, this means that either your view or presenter doesn't behave as expected. You might check whether the presenter subscribed to your view's Connect event, or if your presenter sets the right error message, etc.
The fact is that you never need to test whatever is going on in your private methods, as you shall adjust and bring corrections on debug, which in turn causes you to test the behaviour of your internal methods simultaneously, but no special test method should be written expressly for those helper method.
I have a question regarding unit testing.
I have a function which does the following thing:
void myFunction(List<MyClass> myList) {
// 1. Sort the list
// 2. Post Process the list
}
Now I want to test this function. But the problem is I should not test these two things at the same time. I am therefore thinking to extract the "Post Process the list" part as a separate function.
But the problem is the task of "Post Process the list" is only used by myFunction and I want to make it private to the class.
If I make it private I won't be able to test it from outside.
What is the general rule of this kind of scenario? Must I change a private function to public only for testing?
Or if there are any other patterns I should use?
Many thanks
The test method only needs to be package-local.
You can call private methods using reflections and there are mocking libraries which allow you to test private methods. But I would just make it package-local as it shows the method is access from elsewhere in the package (which it is either way)
As others have said, you don't need to make the method public, just package visible.
Google Guava has a #VisibleForTesting annotation which is meant for situations like this. You put this annotation on a method, just to document that the reason that the method isn't private is only for testing. The annotation doesn't do anything, it's just meant as a warning for programmers that they shouldn't call it from outside the class. (Some static code checking tool could in principle check if methods with this annotation aren't called from anywhere except inside the class or from test code).
Ofcourse it's kind of ugly to have to modify your code to do this just for testing. If you want to avoid this, you can do tricks with reflection to call the private method:
public class Sandbox {
public static void main(String[] args) throws Exception {
Example e = new Example();
Method m = Example.class.getDeclaredMethod("myFunction", List.class);
m.setAccessible(true);
m.invoke(e, Arrays.asList("one", "two", "three"));
}
}
class Example {
private void myFunction(List<String> data) {
System.out.println("Hey, what are you doing! " + data);
}
}
In general, you should always test the functionality through public methods. If there is some functionality in private methods, which cannot otherwise be tested well enough, that's an indication that the method has a responsibility which should be moved to its own class (this also helps to achieve high cohesion). Then that newly extracted class can be tested directly though its public methods.
Another vote for package-local. Just ensure that your newly exposed method is clearly named and documented so that in future it is not called inappropriately.
It depends.
Dose the sub routine contains common behavior that you should extract ?
Take your first sub routine as example. If you're not sorting your list by Comparator<T>, you should refactor it, then test that Comprartor<T> class instead of your private method. If Post process are actually some algorithm or common business logic, you might want to refactor it using Strategy pattern then test those class you just extract.
The point is, if a private method is complex enough to require a unit-test, then chance is probably you should not put them there, otherwise you should just test through it's public API.
It's a legacy system, and it will take forever to refactor that method.
check Bad Smells in Code : Long method for long method refactor, Method Object is a good strategy for things like this.
It's fine, I just want to test them.
Then you can test through Java reflection API, and I believe there are some mocking framework like PowerMock can also help you.
Below things you may consider for testing a private method.
1.create public method written only for the purpose of testing. (or)
2.create nested class for testing (or)
3.use reflection to test it.
useful link,another useful link from stackoverflow
I typically consider private methods to be part of the method under test. They typically consist of code that has been moved out of the original method to make it leaner and shorter, and more modular. However from a test perspective you would be testing the same code if you moved the content of the private method into your method under test.
The question of trying to isolate the return values of private methods to simulate various conditions is is often valid though. I think its' part of the larger question of how to write testable code.
One approach with very little overhead is to rely on basic overriding of methods. You can make your private methods protected virtual instead, and override them in your test:
Here's an example of that too :
http://www.unit-testing.net/CurrentArticle/How-To-Remove-Data-Dependencies-In-Unit-Tests.html
The example is C#, but the concept applies to all object oriented languages
For example , I have a java class as below. I am going to write a unit test for doWork(), so I would like to control obj's behavior. But it is obvious that obj is instantiated internally.
How can I write this UT? Now I am using Junit+Mockito.
class ToBeTest{
public ToBeTest(){}
public boolean doWork(){
OtherObject obj=new OtherObject();
return obj.work();
}
}
Thanks in advance. :)
BTW, The reality is I am writing UT for other person's class. So I don't want to change it. It has been fully tested by integration test.
If you can't change the code, you can use Powermock along with junit and Mockito to mock the construction of new objects.
#Test
public void testDoWork() throws Exception{
MyTest mytest = new MyTest();
OtherObj obj = new OtherObj();
obj.test="mocked Test"; //here you can add any other needed values to obj
PowerMockito.whenNew(OtherObj.class).withNoArguments().thenReturn(obj);
String result = mytest.doWork();
Assert.assertTrue(result.equalsIgnoreCase("mocked Test"));
}
The best way is to write code to support testing (Test-Driven Development is emphasizing this). At the moment, your code is written in the way which makes it difficult to test.
Please consider using dependency injection, because it helps you mock the dependent object.
This is a classical example where you should use dependency injection.
In short, instead of creating the object (dependency) internally, you pass it in the constructor or use a factory to create what you want (the factory returns the real implementation in production code and another in test). This gives you the possibility to change the implementation when you test.
Look at the examples following the like I provided or google for "Java dependency injection example".
You can't easily. I can think of two ways you can do this and neither are supported out of the box by Mockito or jUnit as far as I'm aware:
1) Byte code manipulation using cglib or similar library which would be moderately difficult to do and likely pretty fragile.
2) Alternate classloader. You can build a classloader that looks for an attempt to load the OtherObject class and replaces it with an anonymous OtherObject class that gives you the mocking behavior that you are looking for.
Most of the time you should be treating it as a dependency though. If you want to test opening a file, you probably actually want to test with a file so using the concrete class is probably fine. If you want to test a method's behavior that has opening a file as a part of it's logic, you could easily move that out to a dependency and then mock it out. In fact, that usually makes sense because what you store in a file one day, may need to be stored in a database another or be pulled down from the cloud on a third day, so segregating the logic around what you do with the file from the actual process of opening a retrieving the contents is often a logical separation of concerns anyway.
It's very easy:
import org.junit.*;
import mockit.*;
#Test
public void justMockIt()
{
new NonStrictExpectations() { OtherObject o; { o.work(); result = true; }};
assert new ToBeTest().doWork();
}
... when using JMockit.
You have written your code, and now you want to unit test it. This is the fundamental cause of your difficulty. I suggest a different approach.
Express what the doWork() method is meant to do in terms of behaviour that can be observed only through public and protected (getter) methods of the ToBeTest class, or the public and protected methods of any objectys associated-with ToBeTest objects. Take a look at the Javadoc provided with the Java library: that describes what all those classes do without stating the bodies of the methods. When does yor method return true? When does it return false? What side effects does it have? You might find you need to add some getter methods to do this. You could express these in the Javadoc for your own code.
Use the required behaviour to decide what kinds of assertions you can place in your unit-tests.
I want to intercept all method invocations to some class MyClass to be able to react on some setter-invocations.
I tried to use dynamic proxies, but as far as I know, this only works for classes implementing some interface. But MyClass does not have such an interface.
Is there any other way, besides implementing a wrapper class, that delegates all invocations to a member, which is an instance of the MyClass or besided using AOP?
As you note, you cannot use JDK dynamic proxies (no interface), but using Spring and CGLIB (JAR included with Spring), you can do the following:
public class Foo
{
public void setBar()
{
throw new UnsupportedOperationException("should not go here");
}
public void redirected()
{
System.out.println("Yiha");
}
}
Foo foo = new Foo();
ProxyFactory pf = new ProxyFactory(foo);
pf.addAdvice(new MethodInterceptor()
{
public Object invoke(MethodInvocation mi) throws Throwable
{
if (mi.getMethod().getName().startsWith("set"))
{
Method redirect = mi.getThis().getClass().getMethod("redirected");
redirect.invoke(mi.getThis());
}
return null;
}
});
Foo proxy = (Foo) pf.getProxy();
proxy.setBar(); // prints "Yiha"
If you are prepared to do something really ugly, have a look at:
http://docs.oracle.com/javase/7/docs/technotes/guides/jpda/
Basically the debugger interface ought to allow you to attach like a debugger, and hence intercept calls. Bear in mind I think this is a really bad idea, but you asked if it was possible.
Java doesn't have any actual language features for method interception (not sure any static language does)
I kinda like Nick's idea of using the debugger interface, that's just mean.
I think the short answer you need is: No there isn't a way of intercepting a method call in Java without actually replacing the class using a proxy or wrapper.
Note: The AOP libraries just make this happen automatically.
Some of the Java gurus might frown upon this but I've had some good success with avoiding primitive types and setters altogether. My class looks like this:
class Employee extends SmartPojo {
public SmartString name;
public SmartInt age;
}
You'll notice two things: 1. everything is public. 2. No constructor.
The magic happens in SmartPojo which searches for any field which implements the "Smart" interface and initializes it. Since this is no primitive (and no final class), I can add set() and get() methods for all fields anywhere in my model in a single place. So no setter/getter wastes anymore, it's stunningly simple to add notification (also in a single place), etc.
True, this is no POJO anymore and it's not a Bean in most ways but I've found that these old ideas limit me more than they help. YMMV.
I just developed a small framework for this purpose.
You can check it out at: http://code.google.com/p/java-interceptor/ (use svn to check out).
There isn't a lot of magic in AspectJ. You can write your own agent. http://java.sun.com/javase/6/docs/api/java/lang/instrument/package-summary.html seems to be good starting point.
Why cannot your class implement an interface? You could just extract some interface from it containing all the methods that you want to intercept and use the dynamic proxies mechanism easily. It's also a good programming practice to code with interfaces and not classes.
You could use Spring framework with Spring AOP capabilities (which are using dynamic proxies inside) to do it. You will just have to define your class as a Spring bean in the configuration file and clients of your class will have to either get its instance from the Spring application context or as a dependency automatically (by defining the setMyClass(MyClass mc) method for instance). From there you can easily go to defining an aspect that intercepts all the method calls to this class.