I have a interface fly and a class duck which implements fly.
interface Fly {
getWingSize();
}
public class Duck implements Fly {
#Override
int getWingSize(){
return 1;
}
}
In my controller class, when I try to use the following:
Fly flyAnimal = Animal.getFlyingAnimal();
((Duck) flyAnimal).getWingSize();
It works fine, however in my junit, it gives a class cast exception. I am using powermockito.
In your code you are casting to concrete class (duck). In general, you would mock interfaces. Your test case might have mocked interface fly.
It should work fine if you replace ((duck) fly).getWingSize(); with fly.getWingSize();
Related
I have a interface where my interface extends the spring PagingAndSortingRepository. I want to write unit test case. How can I write unit test case for this.
public interface LookUpRepository extends PagingAndSortingRepository<Lookup, Long> {
public List<Lookup> findAll();
}
can some body help .........
Thanks in advance.
So because this class is an interface, it doesn't have any internal logic. As a result, it doesn't really make sense to unit test it. Instead, you should unit test the implementations of the interface.
A pattern which I have seen is to define a set of unit tests on the interface and then extend that unit test for each implementation. This makes sure that the implementations all adhere to the interface.
public abstract class LookUpRepositoryTest {
public abstract LookUpRepository getRepository();
// ... your tests ...
}
public MyLookUpRepositoryTest extends LookUpRepositoryTest {
#Override
public LookUpRepository getRepository() {
return new MyLookUpRepository();
}
}
As I'm looking at your code, it appears to be using Spring data. If this is the case, you will need to look at Spring unit testing.
My question is about testing a class that implements many interfaces. For example, I have this class:
public class ServiceControllerImpl extends ServiceController implements IDataChanged, IEventChanged {
}
Now there are two ways for testing. The first is testing directly on the concrete class. That means the object type is the concrete class rather than the interface.
public class ServiceControllerImplTest {
ServiceControllerImpl instance;
#Before
public void setUp() {
instance = new ServiceControllerImpl();
// you can bring this instance anywhere
}
}
The second way is testing on the interface only. We must typecast this object to all interfaces it implements.
public class ServiceControllerImplTest {
ServiceController instance; // use interface here
IDataChanged dataChangeListener;
#Before
public void setUp() {
instance = new ServiceControllerImpl();
dataChangeListener = (IDataChanged) instance;
// instance and dataChangeListener "look like" two different object.
}
}
I prefer the second solution because maybe in future we can change the interface it implements to other objects, so using the concrete class might lead to failing tests in the future. I don't know the best practice for this problem.
Thanks :)
I prefer second solution because in reality, maybe in future we can change the interface it implements to other objects, so force using concreted class maybe leads to fail test in the future.
I guess it will lead to failed tests anyway, because you usually test that assertions are true or false. The question is: Do that tests apply to any IDataChanged or do these assertions only apply to the ServiceControllerImpl?
If the assertions only apply to the ServiceControllerImpl it doesn't matter if you use an IDataChanged instead of an ServiceControllerImpl, because you must edit the test when you use another IDataChanged object - different assertions. The test will fail if you use another object.
The way you setup unit tests Itself gives you an answer. A unit test usually tests one class in isolation. This means that you mock the environment. But mocking the environment means that you know the dependencies of the class you test and this are implementation details. So your test is written on an implemtation basis rather than only the interface.
It's possible to write tests that only test an abstract api - like an interface. But this usually means that your tests are abstract too. E.g.
public abstract class SetTest {
#Test
public void addAlreadyExistentObject(){
Set<String> setUnderTest = createSetUnderTest();
Assert.assertTrue(setUnderTest.isEmpty());
boolean setChanged = setUnderTest.add("Hello");
Assert.assertTrue(setChanged);
setChanged = setUnderTest.add("Hello");
Assert.assertFalse(setChanged);
Assert.assertEquals(setUnderTest.size(), 1);
}
protected abstract Set<String> createSetUnderTest();
}
You can then extend these abstract tests to test the api for concrete classes. E.g.
public class HashSetTest extends SetTest {
#Override
protected Set<String> createSetUnderTest() {
return new HashSet<String>();
}
}
In this case you can replace the implementation and the test must remain green.
But here is another example of an abstract api when replacing the object under test does not really make sense.
What about writing a test for all Runnables?
public class RunnableTest {
#Test
public void run(){
Runnable runnable = ...;
// What to test here?
// run is invoked without throwing any runtime exceptions?
runnable.run();
}
}
As you can see it does not make sense in some cases to write tests in a way so that you can easily replace the object under test.
If an api like the Set api defines a concrete state handling you can write abstract tests that test this.
JayC667 already correctly answered that it's best to refer to a class through its supertype(s) in tests of methods defined by those types. But I'd change the way you did that a bit to avoid casting:
public class ServiceControllerImplTest {
ServiceController controller;
IDataChanged dataChangeListener;
#Before
public void setUp() {
instance = new ServiceControllerImpl();
controller = instance;
dataChangeListener = instance;
}
}
I´m trying to write a custom Runner which simply does the Tests in a random order. The runner:
public class TestClassRunnerForParameters extends BlockJUnit4ClassRunner {
public TestClassRunnerForParameters(Class<?> type) throws Exception {
super(type);
}
protected java.util.List<org.junit.runners.model.FrameworkMethod> computeTestMethods() {
java.util.List<org.junit.runners.model.FrameworkMethod> methods = super
.computeTestMethods();
Collections.shuffle(methods);
return methods;
}
}
Now this works fine if it is not a parameterized Test. Is it possible to do this using a Parameter Test? Implementing the Parameterized interface?
I'd say the error is pretty self-descripting:
Custom runner class TestClassRunnerForParameters should have a public constructor with signature TestClassRunnerForParameters(Class testClass)
Your class has no constructor with that signature. Its only constructor has parameters Class<?> type, List<Object[]> parameterList and int i. You should remove the latter two arguments. Plus, that constructor isn't public; you should add public in front of it.
Besides, if you're trying to build parametrised tests, you might be intested in the org.junit.runners.Parameterized runner, as it does exactly that. Here's a good tutorial.
Simply add a constructor, (as advised):
public TestClassRunnerForParameters(Class testClass) {
...
}
And have it delegate to your constructor. Your constructors should be public in this case, as JUnit/Surefire is using reflection.
I want my class to implement an interface, but I want to provide the implementation of the methods using ITD in an aspect. Is this possible?
Interface:
public interface CloningService<T> {
public T clone(T object);
}
Default implementation:
public class DefaultCloningServiceImpl implements CloningService<T> {
public T clone(T object) {
// implementation of the clone method
}
}
Specific implementation:
public class PersonService implements CloningService<Person> {
// no code (!)
}
The class PersonService would declare that it implements the CloningService interface, but the actual implementation of the methods would be provided in DefaultCloningServiceImpl and an aspect would introduce them to PersonService.
I followed the example on Eclipse.com and I tried to use #DeclareParents to achieve the above functionality. However, I was getting a compiler error from AspectJ, which had to do with generics. It's as if the #DeclareParents annotation did not expect the generics to be used...
Thank you.
I'd recommend that you use code style aspectj to solve this rather than annotation style.
This could be done simply by having an aspect like this:
aspect CloningServiceAspect {
declare parents : PersonService extends DefaultCloningServiceImpl<Object>;
}
To make this more general and attached to an annotation, you can do something like this:
aspect CloningServiceAspect {
declare parents : (#CloningService *) extends DefaultCloningServiceImpl<Object>;
}
And if you wanted to package this up into a standalone jar, just make sure to add all code that you want to weave adds this jar to its aspect path (if using compile-time weaving).
I found the solution! It involves using the #DeclareMixin annotation from AspectJ to mix the default implementation of the clone() method:
#Aspect
public class CloningServiceAspect {
#DeclareMixin(value = "(#CloningService *)")
public static CloningService<?> createImplementation() {
return new DefaultCloningServiceImpl<Object>();
}
}
And then my service is annotated with #CloningService instead of implementing the interface:
#CloningService
public class PersonService {
// no code
}
I'm readin http://xunitpatterns.com/Test%20Stub.html and have some questions about the use of stubs, for example, in the code shown on the page the author creates a class called TimeProviderTestStub.java for use in test code. I have some doubts about this line in the test code:
TimeDisplay sut = new TimeDisplay();
// Test Double installation
sut.setTimeProvider(tpStub);
Do I need modify my class(SUT) to recieve one object TimeProviderTestSub?
Both the stub and the real class are supposed to implement some interface, i.e. ITimeProvider, and setTimeProvider() should take this interface as its parameter. The interface must expose all methods that the SUT needs to interact with the object, since TimeDisplay can now only use the object through the ITimeProvider interface (which allows us to use a stub instead of the real object in our tests).
In the example, the SUT (TimeDisplay) seems to only need the getTime() method, so the interface should only contain that method:
public interface ITimeProvider {
Calendar getTime();
}
The declaration of the stub should be
public class TimeProviderTestStub implements ITimeProvider { ... }
and the declaration of the real class should be
public class TimeProvider implements ITimeProvider { ... }
Finally, the SUT must change its setter method to accept the interface:
public void setTimeProvider(ITimeProvider timeProvider) { ... }
and also change its internal timeProvider field to be of the type ITimeProvider.
If you do not control the code of the real class (so that you cannot make it implement the interface), you can create an adapter class which wraps the real class and implements the interface.