About use Stubs - Java - java

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.

Related

Enforce subclass to add #Schedule to a method in super abstract class in Java Spring

I have a super abstract class that has some common implemented methods and other abstract methods to be implemented by a subclass. One of the common implemented methods is a method to be annotated as #Scheduled, but I want the subclass to define how this schedule should be defined (fixed delay, fixed rate or cron .. etc). How to implement such behaviour ?
One approach I thought of is to override the method to be scheduled in the subclass such that it just call its corresponding method in the super class and add the #Scheduled on it with the desired definition, but I don't know how to enforce the subclass to do so as this method is not abstract.
Super Abstract Class
public abstract class SuperClass {
public abstract void x();
public void y() {
// Some implementation
}
// Method to be scheduled.
public void scheduledMethod() {
x();
y();
}
}
Subclass
public class Subclass extends SuperClass {
#Override
public void x() {
// Some implementation
}
// How to enforce the developer to add this ?
#Scheduled(cron = "0 0 0 * * ?")
public void scheduledMethod(){
super.scheduledMethod();
}
}
I couldn't get my head around how you could use #Scheduled but, I've an alternative:
In your abstract class, require a method to be implemented by subclasses to return the schedule:
public String getCronString();
Programmatically schedule the task using Scheduler using the method getCronString() that's implemented in your subclasses, to return the cron schedule. Few examples on how to programmatically schedule tasks with Spring boot:
https://www.baeldung.com/spring-task-scheduler
SO Question
Basically, if your subclasses are not implementing public String getCronString(); your code won't compile.
One option would be to check that the #Scheduled annotation is present (or meta-present) at bean creation time. This can be easily achieved using reflection in a #PostConstruct method on the superclass:
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.ClassUtils;
public abstract class SuperClass {
...
#PostConstruct
public void enforceScheduling() {
boolean annotationPresent = AnnotationUtils.getAnnotation(ClassUtils.getMethod(getClass(), "scheduledMethod"), Scheduled.class) != null;
if (!annotationPresent) {
throw new IllegalStateException("#Scheduled annotation missing from scheduledMethod");
}
}
}
This will cause an exception to be thrown at application start-up time when Spring attempts to create the bean, failing fast and making it very obvious what is missing.
One thing I've done in the past in projects with constraints on a class hierarchy that I could not easily check at compile or runtime was to write a unit test that iterated through every concrete (non-abstract) instance of the class and checked whether it met that constraint.
Since this is using Spring, we probably care more that each bean of this type matches the constraint than whether each subclass on the classpath does.
The constraint in this case is that the #Scheduled annotation is present (or meta-present) on the given method in the subclass. The presence of the annotation can be easily achieved using reflection given the Class object of the subclass.
Putting this together, we can write a unit test utilizing this technique:
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.ClassUtils;
#SpringBootTest
public class SuperClassTest {
#Autowired
private List<SuperClass> beansOfThisType;
#Test
public void allBeansMustBeScheduled() {
for (SuperClass bean : beansOfThisType) {
boolean annotationPresent = AnnotationUtils.getAnnotation(ClassUtils.getMethod(bean.getClass(), "scheduledMethod"), Scheduled.class) != null;
assertTrue(annotationPresent, "#Scheduled annotation missing from scheduledMethod for " + bean.getClass());
}
}
}
Checking every object of the type on the classpath rather than just the Spring beans would be a very similar approach; the difference would be the mechanism to get the list of Class objects to check. Getting the matching objects from the classpath is non-straightforward enough that it's outside the scope of this answer. How do you find all subclasses of a given class in Java? lists a number of ways to accomplish it.

Benefits of Using Generics in a Base Class that Also Implement the Same Class

I recently ran across this scenario in code that I didn't write and while there may be some design benefit to this approach, I can't seem to squeeze this rationale out of my own brain. So before I go and look foolish, I'm hoping for some feedback here.
Service interface something like this:
public interface Service {...}
Then, a base class that adds a generic reference to the Service interface where T extends the Service, but then the overall base class also implements the interface. Something like this:
public class ServiceBase<T extends Service> implements Service {...}
Why would you do this? I'm noticing that in practice the extension of ServiceBase always uses the same class name as T as the one that is being declared; so there's not really any magic polymorphic benefit here. Something like this:
public class MyService extends ServiceBase<MyService> {...}
and, the MyService class is never a container for the generic (e.g., I don't believe this is signaling some kind of self-containing list, where MyService could contain a list of MyServices).
Any ideas/thoughts on why someone would do this?
Why would you do this? I'm noticing that in practice the extension of
ServiceBase always uses the same class name as T as the one that is
being declared; so there's not really any magic polymorphic benefit
here.
Generics don't exist to create magic polymorphim. It is mainly a way to add constraints on types at compile time in order to reduce clumsy cast and error type at runtime.
In your case, suppose that ServiceBase class is abstract and has a process() method which needs to create at each call a new instance of the concrete class we declare in the parameterized type.
We call this abstract method createService().
Without using generics, we could declare the method like that public abstract ServiceBase createService().
ServiceBase without generics
public abstract class ServiceBase implements Service {
public abstract ServiceBase createService();
#Override
public void process() {
createService().process();
}
}
With this declaration, the concrete class may return any instance of ServiceBase.
For example, the following child class will compile because we are not forced to change the returned type of createService() to the current declared type.
MyService without generics
public class MyService extends ServiceBase {
#Override
public ServiceBase createService() {
return new AnotherService();
}
}
But if I use generics in base class :
ServiceBase with generics
public abstract class ServiceBase<T extends Service> implements Service {
public abstract T createService();
#Override
public void process() {
createService().process();
}
}
The concrete class has no choice, it is forced to change the returned type of createService() with the parameterized type declared.
MyService with generics
public class MyService extends ServiceBase<MyService> {
#Override
public MyService createService() {
return new MyService();
}
}
I made up an example using your class and interface declarations (except that I made ServiceBase abstract) which should illustrate the use of the generic types:
public interface Service {
int configure(String cmd);
}
public abstract class ServiceBase<T extends Service> implements Service {
private ServiceManager manager;
public ServiceBase(ServiceManager manager){
this.manager = manager;
}
public final void synchronize(T otherService){
manager.configureEnvironment(otherService.configure("syncDest"), configure("syncSrc"));
synchronizeTo(otherService);
}
protected abstract void synchronizeTo(T otherService);
}
public class ProducerService extends ServiceBase<ConsumerService> {
public ProducerService(ServiceManager manager) {
super(manager);
}
#Override
protected void synchronizeTo(ConsumerService otherService) {
/* specific code for synchronization with consumer service*/
}
#Override
public int configure(String cmd) { ... }
}
public class ConsumerService extends ServiceBase<ProducerService> {
public ConsumerService(ServiceManager manager) {
super(manager);
}
#Override
protected void synchronizeTo(ProducerService otherService) {
/* specific code for synchronization with producer service */
}
#Override
public int configure(String cmd) { ... }
}
Imagine we have services managed by a ServiceManager which can configure the environment of the services so that they are ready for synchronization with each other. How a configure command is interpreted is up to the specific service. Therefore a configure() declaration resides in our interface.
The ServiceBase handles the basic synchronization stuff that has to happen generally when two services want to synchronize. The individual implementations of ServiceBase shouldn't have to deal with this.
However ServiceBase doesn't know how a specific implementation of itself synchronizes to a specific other implementation of service. Therefore it has to delegate this part of synchronization to its subclass.
Now generics come into the play. ServiceBase also doesn't know to which type of service it is able to synchronize to. He has also to delegate this decision to its subclass. He can do this using the construct T extends Service
Given this structure now imagine two concrete subclasses of ServiceBase: ProducerService and ConsumerService; The consumer service can only synchronize to the producer service and the other way around. Therefore the two classes specify in their declaration ServiceBase<ConsumerService> respectively ServiceBase<ProducerService>.
Conclusion
Just like abstract methods can be used by superclasses to delegate the implementation of functionality to their subclasses, generic type parameters can be used by superclasses to delegate the "implementation" of type placeholders to their subclasses.
You haven't posted any of the definitions of these classes where the type parameter is used (which would most likely convey the rationale behind this design, or maybe the lack of it...), but in all cases, a type parameter is a way of parameterizing a class, just like a method can be parameterized.
The ServiceBase class implements a Service. This tells us that it implements the contract (methods) of a Service (to be more precise, subclasses of it can act as the implementation).
At the same time, ServiceBase takes a type argument that is a subtype of Service. This tells us that a service implementation probably has a "relationship" with another implementation type (possibly the same type as the current one). This relationship could be anything needed by the specific design requirement, e.g. the type of Service that this implementation can delegate to, the type of Service that can call this service, etc.
The way I read the following declaration
public class ServiceBase<T extends Service> implements Service {...}
is roughly: ServiceBase is a base implementation of a service, which can have a statically typed relationship with some other type of service.
These two aspects are completely independent.

Mocking a generic class with an abstract version of said class

I'm attempting to mock an abstract class, but from what I've seen, I don't think it's possible. We have some classes that use generics, that must extends a specific abstract class. There's a whole group of them and they have been mocked successfully. The abstract class has one method that deals with returning the generic and looks like this:
public abstract class ChildPresenter <T extends ChildView> {
private T view;
public abstract T getView();
}
The class we are testing has the following in it:
public class ParentPresenter {
private ConcreteChildPresenter1 childPresenter1;
private ConcreteChildPresenter2 childPresenter2;
private ConcreteChildPresenter3 childPresenter3;
private ConcreteChildPresenter4 childPresenter4;
List<ChildPresenter> childPresenters;
}
In the constructor, these classes are injected in, using Google Guice, set to the variables, and added to the list of child presenters.
The method under test is one that iterates over all of the childPresenters objects and runs the method getView().
I attempted it this way in my test class:
public class ParentPresenterTest {
private ConcreteChildPresenter1 childPresenter1;
private ConcreteChildPresenter2 childPresenter2;
private ConcreteChildPresenter3 childPresenter3;
private ConcreteChildPresenter4 childPresenter4;
private List<ChildPresenter> childPresenters;
//This is an abstract class
private ChildView childView;
#BeforeTest
public void createInjector() {
Guice.createInjector(...//Creates a fake module and does binding for the variables mentioned earlier
//e.g.
childPresenter1 = mock(ConcreteChildPresenter1.class);
binder.bind(ConcreteChildPresenter1.class).toInstance(childPresenter1);
//e.t.c for other variables
//Same for child view
childView = mock(ChildView.class);
binder.bind(ChildView.class).toInstance(childView);
}
childPresenters = new ArrayList<ChildPresenter>();
childPresenters.add(childPresenter1);
//Add all child presenters
for(ChildPresenter childPresenter : childPresenters) {
when(childPresenter.getView()).thenReturn(childView);
}
}
}
The problem happens at the line when(childPresenter.getView()).thenReturn(childView); as Mockito complains with the following message:
org.mockito.exceptions.misusing.WrongTypeOfReturnValue:
ChildView$$EnhancerByMockitoWithCGLIB$$2f6a4bd5
cannot be returned by getView() getView() should return ConcreteChildView1
*** If you're unsure why you're getting above error read on. Due to the nature of the syntax above problem might occur because:
This exception might occur in wrongly written multi-threaded tests. Please refer to Mockito FAQ on limitations of concurrency testing.
A spy is stubbed using when(spy.foo()).then() syntax. It is safer to stub spies with doReturn|Throw() family of methods. More in javadocs for Mockito.spy() method.
Which I can understand, but it seems a waste to mock each individual concrete ChildView when all I want to do is confirm the mocked ChildView called a single method using the following:
verify(childView, atLeast(childPresenters.size())).getView();
Is there another way to do this? Can I somehow use mocked abstract classes in place of the concrete ones?
EDIT Here is a concrete version of how the getView() method is implemented:
public ConcreteChildPresenter1<ConreteChildView1> {
#Override
public ConreteChildView1 getView() {
view.buildView();
return view;
}
}
And the abstract ChildView class that all child views extend:
public abstract ChildView {
public abstract void buildView();
}
Since each child presenter returns a view of a specific type, you can't, as you already understood, substitute them with mocks of the abstract class ChildView.
There is a way to get at runtime the concrete type of ChildView only if you provide a proper implementation like explained here: Get generic type of class at runtime
Then you may initialize the presenters' mocks in this way:
for(ChildPresenter childPresenter : childPresenters) {
//this getter returns the needed runtime class
when(childPresenter.getView()).thenReturn(mock(childPresenter.getViewType()));
}
Based on the refinements, the mocked ChildView is based on the wrong superclass. I think you can fix it at Guice injector:
Guice.createInjector(...//Creates a fake module and does binding for the variables mentioned earlier
// ...
//Same for child view
childView = mock(ConcreteChildPresenter1.class); // this is the fix
binder.bind(ChildView.class).toInstance(childView);
}

How can we test that a class implements many interfaces?

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;
}
}

Mocking helper class with Mockito

I have a plain helper class with public methods which I am using in the service level class. When I am writing test for the service class and trying to mock this helper class for one of the method it is going inside the methods and running every line. Since code inside this method is more complex I want to mock helper class with method(s) so that I don't have to take care of every detail inside helper class method.
Service Class
class HistoryServiceImpl implements CaseHistory {
#Override
public List<CaseHistoryDto> getCaseHistory(Individual member, Individual provider) {
MemberUtil memberUtil = new MemberUtil();
List<CaseHistoryDto> caseHistoryDtoList = new ArrayList<CaseHistoryDto>();
List<CaseHistory> caseHistoryList = caseDetailDao.fetchCaseHistory(member.getId(), provider.getId());
for(CaseHistory caseHistory : caseHistoryList) {
CaseHistoryDto caseHistoryDto = new CaseHistoryDto();
caseHistoryDto.setMemberInfo(memberUtil.getMemberInfo(member, caseHistory.getCreateDate()));
caseHistoryDtoList.add(caseHistoryDto);
}
return caseHistoryDtoList;
}
}
Test Class
Class HistoryServiceTest {
#Mock MemberUtil memberUtil;
#InjectMocks private HistoryServiceImpl historyServiceImpl = new HistoryServiceImpl();
#Test
public void testGetCaseHistory() {
//why this line going inside real method and executing all lines?
when(memberUtil.getMemberInfo(any(Individual.class), any(Date.class))).thenReturn(member);
}
}
The reason that your test case is running all the lines in the "real" method, is because your mock object is never being used anywhere.
As written, you cannot mock MemberUtil in your HistoryServiceImpl, because you are manually instantiating it in the getCaseHistory() method. You need to make getCaseHistory() get its MemberUtil from somewhere else, so that you can inject your mock version in your test class.
The simplest solution would be to define your MemberUtil as a member variable, so that the #InjectMocks annotation can override the default value:
class HistoryServiceImpl implements CaseHistory {
MemberUtil memberUtil = new MemberUtil();
#Override
public List<CaseHistoryDto> getCaseHistory(Individual member, Individual provider) {
...
}
}
Alternately you could have HistoryServiceImpl accept an externally provided MemberUtil, either in its constructor or via a setter method. You can then easily pass in a mocked version in your test class.
Generally, utility classes are stateless, so another possible solution would be to convert MemberUtil to make all of its methods static. Then you can use something like PowerMock to mock your static methods.

Categories

Resources