Suppose that I want to write a unit test for a method or class that makes sure that the source code of that method does not call a certain Java API method (in this case, Arrays.sort). Is this even possible? The reason for which I want this is because I want to come up with automatic tests that detect if Arrays.sort has been called from anywhere inside a particular method of a particular class, in which case I want to be failing the relevant test. Unfortunately, a text-based approach is purely unsatisfactory, because it would also catch
potential references to Arrays.sort from within source code comments, for instance. Any help appreciated.
You can do it by creating your interface for sorting and an implementation that uses Arrays.sort
public interface SortUtil {}
public class SortUtilImpl implements SortUtil {
public void sort(Collection c) {
Arrays.sort(c);
}
}
Now you must use the interface in your 'client' class for sorting. For unit tests, replace the real implementation by a test mock one. like:
public SortUtilMock implements SortUtil {
public void sort( Collection c) {
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
//... here you check if the sort is called by a forbidden method
}
}
Best regards,
Zied
Related
I want to avoid use interface when it's not needed. For example, there is an interface AAA, and there is a class AAAImpl implementing it, this interface AAA is only being implemented by AAAImpl, and AAAImpl is only implementing one interface, which is this AAA. The argument of doing this is the code is decoupled, it will be easier for unit testing, it leaves more options in the future for adding more features, etc.
Are these arguments valid?
One class implementing one interface is a perfectly valid strategy for designing a class library, as long as the users of your class have no direct access to the implementing class. This is information hiding at its best: the users see what they need to see, while you keep an ability to redesign your implementation in more ways than you could if you let the users access the implementing class directly.
This also gives your users the flexibility to test their code without relying on any of your code outside the interface definition.
Overall, it is a win-win situation with no downsides.
As far as bad uses of interfaces go, there is a number of possibilities:
Interfaces that attempt to do too much - Adding an interface that covers every single method of a class that performs many different tasks is a bad idea, with the exception of "infrastructure interfaces", e.g. interfaces required to define remoting.
Interfaces that attempt to do too little - Such interfaces cover a small part of functionality of the class, without enabling a meaningful task to be performed without making a reference to the implementing class.
Interfaces that provide a poor match for the functionality of the class - for example, adding IComparable<T> or IEquitable<T> to a mutable class.
One of the bad usege of interface is when iterface has more then it's needed and classes which implement the interface will have to implement all those methods which normally shouldn't.
For example, we have interface for printing and we have many different version of printing (from html document without footer, from html doc with footer, from pdf etc).
So our interface will look like:
public interface IPrinter{
public void printHtmlWithFooter();
public void printHtmlWithoutFooter();
public void printPdf();
}
and then you have implementations:
public class HtmlPrinter implements IPrinter{
public void printHtmlWithFooter(){
// some code, printing ....
}
public void printHtmlWithoutFooter(){
// some code, printing ....
}
public void printPdf(){}
}
public class PdfPrinter implements IPrinter{
public void printHtmlWithFooter(){}
public void printHtmlWithoutFooter(){}
public void printPdf(){
// some code, printing ....
}
}
as you see, you need to implement all of these methods in each class even if they are completely empty. Let's imagine that you have 10 different classes which implement IPrinter interface and you want to add one additional method into interface, so you need to do implementation in each of these classes.
That would be one of examples how you should not use interfaces.
Instead of that you should have only:
public interface IPrinter{
public void print();
}
and then client doesn't care how it will be printed and what, he only knows that method print() has to be called and that's it. Concrete classes should take care about concrete implementation.
I know that it is the purpose of the interface and the class can be declared abstract to escape from it.
But is there any use for implementing all the methods that we declare in an interface? will that not increase the weight and complexity of the code if we keep on defining all the methods even it is not relevant for that class? why it is designed so?
The idea of an interface in Java is very much like a contract (and perhaps seen in retrospect this should have been the name of the concept)
The idea is that the class implementing the interface solemnly promises to provide all the things listed in the contract so that any use of a class implementing the interface is guaranteed to have that functionality available.
In my experience this facility is one of the things that makes it possible to build cathedrals in Java.
What you are critizing is exactly the goal interface achieve.
If you don't want to implement an interface, don't declare your class implementing it.
will that not increase the weight and complexity of the code if we
keep on defining all the methods even it is not relevant for that
class?
When you program against an interface, you want the concrete object behind it to implement all its methods. If your concrete object doesn't need or cannot implement all interface method you probably have a design issue to fix.
When any piece of code receives an instance of an interface without knowing what class is behind it, that piece of code should be assured of the ability to call any method in an interface. This is what makes an interface a contract between the callers and the providers of the functionality. The only way to achieve that is to require all non-abstract classes implementing the interface to provide implementations for all its functions.
There are two general ways to deal with the need to not implement some of the functionality:
Adding a tester method and an implementation that throws UnsupportedOperationException, and
Splitting your interface as needed into parts so that all method of a part could be implemented.
Here is an example of the first approach:
public interface WithOptionalMehtods {
void Optional1();
void Optional2();
boolean implementsOptional1();
boolean implementsOptional2();
}
public class Impl implements WithOptionalMehtods {
public void Optional1() {
System.out.println("Optional1");
}
public void Optional2() {
throw new UnsupportedOperationException();
}
public boolean implementsOptional1() {
return true;
}
public boolean implementsOptional2() {
return false;
}
}
Here is an example of the second approach:
public interface Part1 {
void Optional1();
}
public interface Part2 {
void Optional2();
}
public Impl implements Part1 {
public void Optional1() {
System.out.println("Optional1");
}
}
will that not increase the weight and complexity of the code if we
keep on defining all the methods even it is not relevant for that
class?
Yes you are right it will. That is why it is best practice in your coding to follow the Interface Segregation Principle which recommends not to force clients to implement interfaces that they don't use. So you should never have one "fat" interface with many methods but many small interfaces grouping methods, each group serving a specific behavior or sub-module.
This way clients of an interface implement only the needed methods without ever being forced into implementing methods they don't need.
It may depend on Liskov Substitution Principle
So, having A implements B means that you can use A when B is needed and, to make it work without problems, A must have at least the same methods of B.
Please keep in mind that mine is not a "proper" answer, as it's not based on official sources!
When implementing an Interface,we may not need to define all the method declared in the Interface.We can define the some methods,that we don't need,With nothing inside the body.
I have the following class:
class MyClass {
public void doIt() {
methodOne();
methodTwo();
methodThree();
}
private void methodOne() {
// ...
}
// rest of methods similar...
}
My intention is to verify that when i invoke doIt(), methods metodOne(), methodTwo() and methodThree() will be invoked, in that order.
I'm using mockito for mocking. Does anyone knows how i can test this scenario?
Hate to be the person but: simply don't test this. Test the output, side effects, results - not the implementation.
If you really want to ensure the correct order, extract these methods into separate class(es) and mock them.
As long as your private methods are ... well ... private, don't test them. They are implementation details. They could be refactored without changing the contract of your class. Test the correct outcome of your public methods.
I have a class which is implementing an interface, and one of the methods is called onClick. Is there a way to implement the onClick that the interface wants but name it something else? Something like (and I'm making this up):
public void AnyMethodNameIWant() implements Interface1.onClick
Three reasons I'm asking are:
It would be nice to look at an method signature and know that it's
coming from an interface
To avoid 'generic' names like onClick that an interface may require me to have
To distinguish between the same method names in many interfaces
Apologies if this is a fundamentally 'bad' question as I am new to Java.
No, you can't. Interfaces have to be implemented by a method of the same name in Java.
You can use the #Override annotation with interface implementations (as of Java 6) though, which helps to clarify that this is a method which can't just be renamed arbitrarily.
One option for your second issue might be to create an implementation class just for the purpose of forwarding on the call to a more specific method. You might want to do this as a nested or even anonymous class. I'm not sure I'd usually do this though.
EDIT: Having seen the third question - no, if you have two interfaces with the same method signature in Java, you can only provide one implementation :( Oh, and if you've got two interfaces with the same signature but different return types, it's even worse. You could always write a method of Interface1 getInterface1() which returns an instance of an anonymous inner class proxying the Interface1 methods onto the "main" class.
Nope.
The only thing you could do is add a shadow method that implements the interface and calls your method.
public class MyClass implements Interface1 {
public void AnyMethodNameIWant() { ...; }
public void onClick() { AnyMethodNameIWant(); }
}
Those two points
To avoid 'generic' names like onClick that an interface may require me to have
To distinguish between the same method names in many interfaces
are usually solved by using the Adapter Pattern.
interface IFoo {
void onClick();
void onChange();
}
class MyImpl {
void doSomething(){
// real code for onClick
}
void doSomethingElse(){
// real code for onChange
}
IFoo getFooAdapter(){
return new IFoo() {
#Override
public void onClick() {
doSomething();
}
#Override
public void onChange() {
doSomethingElse();
}
};
}
}
Basically you create an intermediate step which forwards all calls to any interface method to the real implementation.
Naming and signatures can vary. You can also offer different adapters for different interfaces if you want (or must if both interfaces have competing method with different behaviour).
There are quite some possibilities how to hand out the adapter instance - creating a new one every time might not be wise in certain circumstances.
Of course this pattern is nothing you implement just for fun or just for minimal and clean code. But it can solve real problems.
You can't rename the method, but you could define both methods (onClick and anyMethodNameIWant) and have onClick just simply call your other method.
#Override
public void onClick() {
anyOtherMethodNameIWant();
}
You of course can have additional methods with different names that point to the same implementation to get the naming you desire.
public void interfaceMethodA(){
// some implementation here
}
public void AnyMethodNameIWant(){
interfaceMethodA();
}
How can I enforce that my test class covers a particular interface?
Also is there a convention for writing overloaded test methods, so the names are consistent (my current technique is something like: methodName + parameter1Type + parameter2Type + ...)?
I'm hoping the second question will be covered/avoided if there is a good way to do the first.
My issue is I have classes which implement a number of interfaces. Since I'm testing Spring injected service classes, everything has at least one interface.
Anyways say I have a class that implements:
public interface MyInterface{
int doFoo(int input);
int doBar(int input);
}
Lets say MyInterfaceImpl, implements this interface.
Now my test class will look something like:
import static org.junit.Assert.assertEquals;
import org.junit.Test;
public class MyInterfaceImplTest{
private MyInterface = new MyInterfaceImpl(); //could inject it...
#Test
public void doFooTest(){
//content of test not relevant
}
#Test
public void doBarTest(){
//content of test not relevant
}
}
Now the above isn't to bad in terms of size, but it's hard to know if I've covered all the testing in larger classes, I could have missed one. Also I find it anyoying to create method names for overloaded methods. I could also add functionality to a class and possibly missed it. If I'm doing TDD this would be nearly impossible but I'd still like to be sure. What I've been tempted to write is...
public class MyInterfaceImplTest implements MyInterface{
And then I'd like to stick #Test in front of each method. Of course this isn't going to work because, well the test needs to put the values in. But using implements lets the IDE add the methods and it enforces that the full interface has been implemented. To be clear I know I am not looking to actually implement the interface in the test, but I think it could speed up development if I could do something like this.
To me this depends on what you mean by "enforce" and "covers a particular interface".
If your interface methods imply certain "contracts" (e.g. java.util.Collection.add() returns true if the receiving collection was modified as the result of the call), that you want to ensure are upheld by implementers of the interface, you can create a Contract Test.
If you want to see that all methods of a test subject are exercised by a particular test class, you can run the test under a code coverage tool like EMMA or Cobertura and ensure the results are to your liking.
You should probably look into parameterized testing. Here is what it would look like with TestNG:
#Test(dataProvider = "dp")
public testInterface(StrategyInterface si) {
// will be invoked twice, one with each implementation
}
#DataProvider
static public Object[][] dp() {
return new Object[][] {
new Object[] { new Strategy1Impl() },
new Object[] { new Strategy2Impl() },
};
}