Suppose I have an interface with lots of methods that I want to mock for a test, and suppose that I don't need it to do anything, I just need the object under test to have an instance of it. For example, I want to run some performance testing/benchmarking over a certain bit of code and don't want the methods on this interface to contribute.
There are plenty of tools to do that easily, for example
Interface mock = Mockito.mock(Interface.class);
ObjectUnderTest obj = ...
obj.setItem(mock);
or whatever.
However, they all come with some runtime overhead that I would rather avoid:
Mockito records all calls, stashing the arguments for verification later
JMock and others (I believe) require you to define what they going to do (not such a big deal), and then execution goes through a proxy of various sorts to actual invoke the method.
Good old java.lang.reflect.Proxy and friends all go through at least a few more method calls on the stack before getting to the method to be invoked, often reflectively.
(I'm willing to be corrected on any of the details of those examples, but I believe the principle holds.)
What I'm aiming for is a "real" no-op implementation of the interface, such as I could write by hand with everything returning null, false or 0. But that doesn't help if I'm feeling lazy and the interface has loads of methods. So, how can I generate and instantiate such a no-op implementation of an arbitrary interface at runtime?
There are tools available such as Powermock, CGLib that use bytecode generation, but only as part of the larger mocking/proxying context and I haven't yet figured out what to pick out of the internals.
OK, so the example may be a little contrived and I doubt that proxying will have too substantial an impact on the timings, but I'm curious now as to how to generate such a class. Is it easy in CGLib, ASM?
EDIT: Yes, this is premature optimisation and there's no real need to do it. After writing this question I think the last sentence didn't quite make my point that I'm more interested in how to do it in principle, and easy ways into dynamic class-generation than the actual use-case I gave. Perhaps poorly worded from the start.
Not sure if this is what you're looking for, but the "new class" wizard in Eclipse lets you build a new class and specify superclass and/or interface(s). If you let it, it will auto-code up dummy implementations of all interface/abstract methods (returning null unless void). It's pretty painless to do.
I suspect the other "big name" IDEs, such as NetBeans and Idea, have similar facilities.
EDIT:
Looking at your question again, I wonder why you'd be concerned about performance of auto proxies when dealing with test classes. It seems to me that if performance is an issue, you should be testing "real" functionality, and if you're dealing with mostly-unimplemented classes anyway then you shouldn't be in a testing situation where performance matters.
It would take a little work to build the utility, but probably not too hard for basic vanilla Java interface without "edge cases" (annotations, etc), to use Javassist code generation to textually create a class at runtime that implements null versions of every method defined on the interface. This would be different from Javassist ProxyFactory (Or CGLib Enhancer) proxy objects which would still have a few layers of indirection. I think there would be no overhead in the resulting class from the direct bytecode generation mode. If you are brave you could also dive into ASM to do the same thing.
Related
Mocking ScheduledExecutorService would really make testing my classes easier, but according to the mockito recommendations this seems a bad idea, as the logic of the mocked class can change in a way that it would be used in an incorrect way, but unit tests would still report success.
It seems that writing a wrapper for it would be the "clean" way, but I have a feeling that this would merely result in the complete duplication of an interface, which would just make my code less straightforward. I'd like to follow the practical recommendations of this answer, but I am not sure that the contract of ScheduledExecutorService will always remain the same.
Can I assume that the contract for the existing methods of ScheduledExecutorService (or more generally, any other class in the JRE libs) will never change? If not, is it enough if I test the correct use of it in the integration tests, while still mocking it directly in the unit tests?
It's more of a guideline than a rule; do the thing that will most likely result in a clean, reliable, and non-brittle test. As in the document you quoted:
This is not a hard line, but crossing this line may have repercussions! (it most likely will)
One important thing here is that "don't mock types you don't own" usually refers to concrete or internal types, because those are much more likely to change their behavior between versions, or to gain or lose modifiers like final or static that Mockito's dynamic overrides might not pick up on. After all, if you were to subclass a third-party class manually, Java would throw a compiler error; Mockito's syntax would hide that from you until test runtime.
To list out the factors I think of:
As assylias pointed out in the comments, you're referring to a Java interface, which insulates you from common changes to final methods or method visibility.
The interface is well-documented and designed for third-party extension, providing yet another reason that Java would be unlikely to make breaking changes to the general contract of the interface.
The interface in question is a very well-used interface in Java, which overall has a lot of users, and a lot of backwards-compatibility concerns. It is very unlikely that you'd be subject to breaking changes, compared to a smaller library, or one under active development. One might even say that the JRE is in such lock step to the Java language, you have as much to worry about from breaking syntax changes than from breaking interface changes.
Though I believe strongly in "don't mock types you don't own" as a general heuristic or code smell, I'd agree with you here that the type is worth mocking, and that—unless you were to write and test a full implementation to be used in other tests—it's the best path forward for you here.
I'd say the "Don't mock type you don't own!" is the false conclusion out of the right reasoning.
Unittests should only need to be changes if your API changes or the part of an API of a dependency your code uses.
example:
You us an interface of a dependency as an input parameter, but your tested code uses only one method in that interface. If you don't mock this interface (which is a type you don't own) you have to create your own dummy implementation implementing all of the interfaces methods, even those you don't use.
If you change the version of that dependency this interface might have additional method and/or some methods have been removed. You have to change all of your the implementations of this interface throughout your program. If you mocked this interface you don't need to change your tests and they still give you confidence that your codes behavior did not change after the required refactoring.
Furthermore your Unittest should only fail because the behavior of your code changed, not because of a change in the dependencies behavior.
Changes in a dependencies behavior should be pinned with separate Unittest you setup for the dependencies behavior (if it is crucial for your application) and/or integration tests.
I'm taking over an old project. Now I have some classes in the flavor of own util class overriding a util class of external library. E.g.:
public final class StringUtilsXXX extends org.apache.commons.lang3.StringUtils {
}
These classes are not overriding any methods of the extended class at all (and never will be in the future). I find it confusing, that most calls on the own implementation are just delegating to the super class. Is this bad practice?
Yes. This is bad practice. The argument for why is that it tightly couples your own classes to a third party library. I'm sure the reason your predecessor did this, is so that if he needed to some day replace commons-lang, he would only have to change one piece of the code. He probably did this because of frustration from upgrading from lang2 to lang3.
The way he should have done this, would have been to create a StringUtil interface, and write different implementations of this (you could have a StringUtil which was implemented using lang2, one that used lang3 and even maybe a fallback implementation that was implemented from scratch. (if you needed some string handling not provided by either, or if you needed to compile some versions with an older Java version, or whatever).
Normally not needed if you are not overriding anything or adding any data or method member in subclass. However, for future placeholder, this may be used.
It will not hurt for now. But using (has a) StringUtils should be preferred over extending it, if no additional behavior is provided.
If there is an interface available for StringUtils and you are pointing your implementation (extending class instance using it) then it might still make some sense from maintainability point of view (that again depends on how you are instantiating it).
I don't consider it as a bad practice necessarily. There are cases that you may not want to rely on the API of an external library, and you might want to build a wrapper layer between the client (your) code and the external library. The reason doing this would be that you have control of the API of the wrapper contrary to the API of the external library.
I guess what he really did, from the pattern standpoint, is a decorator. I don't know anything about this particular library (because I'm a .net dev) and does it expose interfaces that he should implement instead but I would rephrase the question to:
Is it fine to create decorators on 3rd party libraries or should we make adapters instead.
As far as I see it, adapters are the right answer. But there is something more that puzzles me here: shouldn't we always try as hard as we can not to break contract when upgrading our project we give away to others? Did "they" have to introduce new namespace?
If they did, should we blame our colleges for hacking code to maintain project despite someone else's doubtful ideas/solutions?
No.. This is a bad practice. Suppose tomorrow org.apache.commons.lang3.StringUtils changes something (removes a method. Though it is unlikely, it can still happen with other classes especially with custom classes), imagine the impact it would have on your code. You are actually tightly coupling your methods with org.apache.commons.lang3.StringUtils.
It seems to be the standard so I have been going along with it so far, but now I am building a new class from scratch instead of modifying the old ones and feel I should understand why I should follow the projects convention.
Almost every class has an interface to it which is called classnameable. In the code database.class would never appear even once but in place where I would want to use that class I see databaseable.class.
To my understanding an interface was a class that was never implemented but was inhereted from to keep standards. So why are the interfaces being used as if they were real classes?
To my understanding an interface was a class that was never
implemented but was inhereted from to keep standards. So why are the
interfaces being used as if they were real classes.
This is a bit confused. An interface defines an API, so that pieces of code from different authors, modules or projects can interact. For example, java.util.Collections.sort() can sort anything that implements the List interface and contains objects that implement the Comparable interface - even though the implementation classes may not have existed yet when the sorting code was written!
Now the situation in your project seems to reflect an unfortunately rather common antipattern: having an interface for everything, mostly with a single implementation class, even for internal classes.
This used to be strongly promoted by proponents of Test-Driven-Development (TDD) who see it as vital to be able to test every class in isolation with all its dependencies replaced by mock objects. Older mocking frameworks could only mock interfaces, so to be able to test every class in isolation, all inter-class dependencies had to be through interfaces.
Fortunately, newer mocking frameworks can mock concrete classes and don't require you to pollute your project with unnecessary interfaces. Some people will probably still argue that it should be done anyway to "reduce coupling", but IMO they're just rationalizing their desire not to change their practices.
And of course, if you don't do fundamentalist TDD, there never was a good reason to have an interface for everything - but very good reasons to have interfaces for some things.
If you've got an interface for pretty much every single class in your project even though there's no reason for it, that's not a good thing and in this day and age there's no great reason for it. It may be a legacy from days gone by when it was required by some external testing toolkit for instance - but these days that's not a requirement.
It may be of course that someone's heard that loose coupling is a good thing, that you should always couple to interfaces and not concrete classes, and taken this idea to an extreme.
On the other hand, it is good practice to define interfaces for some classes even if there's only one of them (at the moment.) When I'm writing a class I try to think along the lines of whether another (potentially useful) implementation could exist, and if so I'll put an interface in. If it's not used it's no problem, but if it is it saves time and hassle and refactoring later.
If you want a class for your interfaces then a common way is to create an AbstractFoo class to go with the Foo interface. You can provide simple implementation of the required methods, allowing derived classes to overwrite them as needed. See AbstractCollection for an example of such a class.
The advantage is that you don't have to implement all the small stuff, it is already done for you. The disadvantage is that you can't inherit from any other class. You pays your money and you takes your choice.
A good indication for bad design is when you have a ISomething or a SomethingImpl. The interface name should state how to use it (i.e. List), the class name should state how it works (i.e. ArrayList).
If you need pre- or suffixes because the names would be the same, this means there is only one way to implement it, and then there is probably no need for a separation. (If you think there will be more sophisticated implementations in the future, name your class DefaultSomething or SimpleSomething)
After comming from Ruby world, I'm having little problems doing TDD in Java. The biggest issue is when I have application that is just communicating with external API.
Say I want to just fetch some data from Google Calendar, or 5 tweets from some Twitter user and display it.
In Ruby, I don't have any problems, because I can monkey-patch the API library in tests directly, but I have no such option in Java.
If I think about this in terms of MVC, my model objects are directly accessing the API through some library. The question is, is this bad design? Should I always wrap any API library in some interface, so I can mock/stub it in Java?
Because when I think about this, the only purpose of that interface would be to simulate (please don't kill me for saying this) the monkey-patch. Meaning that any time I use any external resource, I have to wrap each layer in interface that can be stubbed out.
# do I have to abstract everything just to do this in Java?
Twitter.stub!(:search)
Now you might say that I should always abstract away the interface, so I can change the underlying layer to anything else. But if I'm writing twitter app, I'm not going to change it to RSS reader.
Yes, I can add for example Facebook and then it would make sense to have interface. But when there is no other resource that can be substituted for the one I'm using, than I still have to wrap everything in interfaces to make it testable.
Am I missing something, or is this just a way to test in the Java world?
Using interfaces is just generally good practice in Java. Some languages have multiple inheritance, others have duck typing, Java has interfaces. It's a key feature of the language, it lets me use
different aspects of a class in different contexts and
different implementations of the same contract without changing client code.
So interfaces are a concept you should embrace in general, and then you would reap the benefits in situations like this where you could substitute your services by mock objects.
One of the most important books about Java best practices is Effective Java by Joshua Bloch. I would highly suggest you to read it. In this context the most important part is Item 52: Refer to objects by their interfaces. Quote:
More generally, you should favor the use of interfaces rather than
classes to refer to objects. If appropriate interface types exist, then parameters, return values, variables, and fields should all be declared using interface
types. The only time you really need to refer to an object’s class is when you’re
creating it with a constructor.
And if you take things even further (e.g. when using dependency injection), you aren't even calling the constructor.
One of the key problems of switching languages is that you have to switch the way of thinking too. You can't program language x effectively while thinking in language y. You can't program C effectively without using pointers, Ruby not without duck typing and Java not without Interfaces.
Wrapping the external API is the way I would do this.
So, as you already said, you would have an interface and two classes: the real one and the dummy implementation.
Yes, it may seem unreasonable from the perspective of some services indeed being specific, like Twitter. But, this way your build process doesn't depend on external resources. Depending on external libraries isn't all that bad, but having your tests depend on actual data present or not present out there on the web can mess up the build process.
The easiest way is to wrap the API service with your interface/class pair and use that throughout your code.
I understand that what you want are Mock objects.
As you described it, one of the ways one can generate "test versions" of objects is by implementing a common interface and using it.
However, what you are missing is to simply extend the class (provided that it is not declared final) and override the methods that you want to mock. (NB: the possibility of doing that is the reason why it is considered bad form for a library to declare its classes final - it can make testing considerably harder.)
There is a number of Java libraries that aim in facilitating the use of Mock objects - you can look at Mockito or EasyMock.
Mockito is more handy and like your ruby mocks.
You can "monkey-patch" an API in Java. The Java language itself does not provide specific means to do it, but the JVM and the standard libraries do. In Ruby, developers can use the Mocha library for that. In Java, you can use the JMockit library (which I created because of limitations in older mocking tools).
Here is an example JMockit test, equivalent to the test_should_calculate_value_of_unshipped_orders test available in Mocha documentation:
#Test
public void shouldCalculateValueOfUnshippedOrders()
{
final Order anOrder = new Order();
final List<Order> orders = asList(anOrder, new Order(), new Order());
new NonStrictExpectations(Order.class)
{{
Order.findAll(); result = orders;
anOrder.getTotalCost(); result = 10;
}};
assertEquals(30, Order.unshippedValue());
}
Is there any way we can inject new methods and properties into classes during run-time.
http://nurkiewicz.blogspot.com/2009/09/injecting-methods-at-runtime-to-java.html states we may do that by using Groovy.
Is it possible by just doing using Java?
Is it possible by just doing using
Java?
The simple answer is an emphatic "You don't want to do that!".
It is technically possible, but not without resorting to extremely complex, expensive and fragile tricks like bytecode modification1. And even then, you have to rely on dynamic loading to access the modified type and (probably) reflection to make use of its new members. In short, you would be creating lots of pain for yourself, for little if any gain.
Java is a statically typed language, and adding / modifying class type signatures can break the static typing contract of a class.
1 - AspectJ and the like allow you to inject additional behaviour into a class, but it is probably not the "runtime" injection that you are after. Certainly, the injected methods won't be available for statically compiled code to call.
So if you were really crazy, you could do something like what they outline here. What you could do is load the .java file, find the correct insertion point, add whatever methods you need to, call the java compiler and reload the class. Good luck debugging that mess though :)
Edit This actually might be of some use...
You can do some quite funky things with AOP, although genuine modification of classes at runtime is a pretty hairy technique that needs a lot of classloading magic and sleight of hand.
What is easier is using AOP techniques to generate a subclass of your target class and to introduce new methods into this instead, what AOP called a "mixin" or "introduction". See here to read how Spring AOP does it, although this may be quite lame compared to what you're actually trying to achieve.
Is it possible by just doing using Java?
Quite so, the "only" thing you have to do is define an instrumentation agent which supplies an appropriate ClassFileTransformer, and you'll have to use reflection to invoke the added methods. Odds are this isn't what you want to do, though, but it's doable and there's a well-defined interface for it. If you want to modify existing methods you may be interested in something like AspectJ.
While it might be possible, it is not useful.
How would you access these new fields and methods?
You could not use these methods and fields directly (as "ordinary" fields and methods), since they wouldn't be compiled in.
If all you want is the possibility to add "properties" and "methods", you can use a Map<String, Object> for the "dynamic properties", and a Map<String, SuitableInterface> for the "dynamic methods", and look them up by name.
If you need an extension language for Java, an embedded dynamic language (such as Javascript, or Groovy) can be added; most of these can access arbitrary java objects and methods.