Java - Unit test cases for delegating class - java

I have a service class MyBusinessService with 2 methods doABC() and doXYX(). Method doABC() delegates the work to ABCHandler.do() and method doXYX() delegates the work to XYZHandler.do(). MyBusinessService class methods just delegates the works to corresponding handlers.
I have a question here. When i write Unit test for this, i must write unit tests for the methods in the handlers. Should i write UT for MyBusinessService class methods. I ask this question for 2 reasons.
a. With UT tests, one functionality should not be tested in 2 places. My actual logic is in handler classes and i should not unit test the same logic in both handler class and service class
b. If i dont write unit test for MyBusinessService class methods, then in the future if some developer makes some bug fix and breaks something, then it may cause the application to fail in production. So, i need a test here. But if i write test case for this class, this will break rule (a).
Please let me know whether i should write UT for delegating class(MyBusinessService class) or should i leave it to Integration test cases to address it.

Unit test must test only one class. If you test interaction of more than one class instances so you're doing integration testing. You should consider using some mock library like jmock or mockito, the first one fit better for my uses.
If you use jmock you can do as above:
#Test
public void someTestMethod(){
MyBusinessService instance = new MyBusinessService()
Mockery context = new Mockery();
ABCHandler mock1 = context.mock(ABCHandler.class); //creating a mock object
instance.setABCHandler(mock1);
context.checking(new Expectations(){{
oneOf(mock1).do(); //creating a expectation wich expects exactly on call of method do.
}});
instance.doABC();
context.assertIsSatisfied(); //check if the expectation is met
}

Related

How to mock ArrayList class using using whenNew method

I'm trying to mock arraylist to verify the add method but I'm getting the message:
FAILED: testInit
Wanted but not invoked:
arrayList.add(<any>);
-> at AsyncRestTemplateAutoConfigurationTest.testInit(AsyncRestTemplateAutoConfigurationTest.java:95)
Actually, there were zero interactions with this mock.
The test class I've used is:
#Test
public void testInit() throws Exception {
ArrayList<AsyncClientHttpRequestInterceptor> interceptors = Mockito.mock(ArrayList.class);
PowerMockito.whenNew(ArrayList.class).withAnyArguments()
.thenReturn(interceptors);
Mockito.stub(interceptors.add(Mockito.any())).toReturn(true);
asyncRestTemplateAutoConfiguration.init();
Mockito.verify(interceptors).add(Mockito.any());
}
The actual tested code is:
List<AsyncClientHttpRequestInterceptor> interceptors = new ArrayList<>(interceptors);
interceptors.add(new TracingAsyncRestTemplateInterceptor(tracer));
I've declared the test class with
#RunWith(PowerMockRunner.class)
#PrepareForTest(AsyncRestTemplateAutoConfiguration.class)
Where AsyncRestTemplateAutoConfigurationis the class, which I'm using to test. Could anyone please tell me what I'm missing?
Your unit test should verify public observable behavior which is return values and communication with dependencies (which does not nessessarily imply to test only public methods).
That your production code uses an ArrayList to store your data is an implementation detail which you don't want to test since it may be changed without changing the units general behavior, in which case your unittest should not fail.
Don't start learning how to unit test using PowerMockito - it will give you bad habits.
Instead, consider working carefully through the documentation for Mockito and you will see how to structure your classes for better testing.
Ideally, your classes should be such that you do not need PowerMockito to test them and you can just rely on plain old Mockito.
If you can arrive at the point where you can write elegant and simple tests using just Mockito, it will be a sign you have grasped the fundamental concepts of unit testing.
You can start by learning how to inject dependencies through the constructor of the class that can be swapped with mocked test doubles on which behaviour can be verified.
Another point to note is, as per the other answer, the internal ArrayList in your system under test is an implementation detail. Unless consumers of your system under test can access the ArrayList through, say, methods that expose it there is not much point in writing a test against it.
If the state of the internal ArrayList affects something from the point of view of the consumer, then try writing a test against that rather than against the internal property.
Good luck with your journey on unit testing!

Mockito method call without object

The code has something like
Speed speed = readSpeed(Point A, Point B);
isOverLimit = limitCheck.speedCheck(speed);
How do I use mockito for read speed?
Mockito.when(readSpeed(0, 0).then...
suppose should I use the class object to call this?
Mockito effectively works by creating individual subclasses of objects that delegate every overridable implementation to the mock framework.
Consequently, you can't use Mockito mock your method (readSpeed) for all instances at once or instances created in your system under test, nor mock any static or final methods. If readSpeed is any of those, or need to be mocked on an instance you don't touch in your test, Mockito will not work for you; you'll need to refactor, or use PowerMockito (which quietly rewrites your system under test to redirect constructors, final calls, and static calls to Mockito's framework).
If readSpeed is a public non-final instance method on your system under test, then you can mock it, and that'd be called a partial mock of your component. Partial mocks can be useful, but can also be considered "code smells" (as mentioned in the Mockito documentation): Ideally your test class should be an atomic unit to test, and mocking should happen for the dependencies around your system under test rather than your test itself. Otherwise, you could too easily test the spec or test the mocking framework rather than testing your component.
Though the better thing to do would be to split the class into smaller interconnected components, you can use partial mocking in Mockito like this:
#Test public void componentChecksSpeed() {
YourComponent yourComponent = Mockito.spy(new YourComponent());
// Use doReturn, because the when syntax would actually invoke readSpeed.
doReturn(65).when(yourComponent).readSpeed(any(Point.class), any(Point.class));
yourComponent.run();
}

Reuse expectations block several times in JMockit

I am writing test cases for a liferay portal in which I want to mock ActionRequest, ThemeDisplay kind of objects. I have tried with writing expectations in each test method.
Now I want to generalize the approach by creating a BaseTest class which provides me all expectations needed for each method so that I don't have to write it again in the all test classes.
For one class I have tried by writing expectations in #Before method. How can I use same in different classes?
For example I want to do following in several classes:
#Before
public void setUp() {
// All expectations which are required by each test methods
new Expectations() {{
themeDisplay.getPermissionChecker();
returns(permissionChecker);
actionRequest.getParameter("userId");
returns("111");
actionRequest.getParameter("userName");
returns("User1");
}};
}
Also is there a way to provide that whenever I call actionRequest.getParameter() it may return the specific value which I provide?
Any help will be appreciated.
Generally, what you want is to create named Expectations and Verifications subclasses to be reused from multiple test classes. Examples can be found in the documentation.
Note that mocked instances have to be passed in, when instantiating said subclasses.
Methods like getPermissionChecker(), however, usually don't need to be explicitly recorded, since a cascaded instance is going to be automatically returned as needed.
Mocking methods like getParameter, though, hints that perhaps it would be better to use real objects rather than mocks. Mocking isn't really meant for simple "getters", and this often indicates that you may be mocking too much.

Mockito Mocking a return value and verify it

I have this class and wants to create a mock to return and verify the return value "50":
QAService.java:
#Path("/QAService")
public class QAService {
#GET()
//#Path("/")
#Produces("text/plain")
public String getServiceInfo() {
return "50";
}
My understanding of mock by defintion is that I can create a fake object of an implementation class and mock functions yet to be developed so I can test the interface.
Still I am creating this test to test mocking without having an interface. How do I verify it?:
QAServiceTest.java:
public class QAServiceTest {
#Test
public void getserviceTest () {
QAService qasmock = mock(QAService.class);
when(qasmock.getServiceInfo()).thenReturn("50");
String expected = "50";
assertEquals(expected, qasmock.getServiceInfo());
}
}
Junit will only run methods annotated with #Test, so add it
#Test
public void getserviceTest () {
QAService qasmock = mock(QAService.class);
when(qasmock.getServiceInfo()).thenReturn("50");
String expected = "50";
assertEquals(expected, qasmock.getServiceInfo());
}
Also, you should verify() that your mock expectations actually happened.
verify(qasmock, times(1)).getServiceInfo();
Note that it seems like you want to test QAService, but you really aren't doing that here. You are simply testing a mock. That's not the same thing.
Create the QAService object yourself and use it.
Let's get a couple definitions straight, first:
A unit test is a brief bit of code you write to ensure that the system you've developed is behaving correctly. Unit tests are often created in a framework like JUnit, but do not need to be. For example, a unit test would assertEquals(5, calculator.add(2, 3)).
A mock is an imitation of a real system, which is often used in unit tests. Mocks are often created in frameworks like Mockito or EasyMock, but do not need to be. Mocks are a form of "test double"—the general term for code you substitute in place of your actual systems, for testing purposes—and Martin Fowler defines them more exactly in an article called "Mocks Aren't Stubs".
When writing a unit test, you're trying to test a single unit, which is often called the system under test or SUT for short. Each test will probably have a different system under test, and the point is that the code that you are testing in the test is your real, actual code, not any sort of mock or fake implementation.
In a complex application, your classes will probably need to collaborate with other classes that may or may not be written or tested, which are categorically known as dependencies. Any given class or system may have its own dependencies, and may be a dependency for other systems. Mocking frameworks are good for mocking those dependencies, not for mocking the system under test.
For your example, QAService is the main class you're writing (system under test), and QAServiceTest is the unit test for that system. No mocks are necessarily required.
Let's say that QAService depends on another class not yet written, called "StorageService". You don't necessarily want to wait for StorageService to work before writing QAService's tests, so instead of using a real StorageService you use a mock. Again, in the unit test called QAServiceTest, you use a real QAService and mock its dependency StorageService.
Even though you don't have StorageService written, you probably have some expectation about how QAService will use that class. Maybe you know that when you call storageService.store(qaRecord), it should return a numeric ID like 101. Even without the code working, you can create a Mockito mockStorageService, and prepare it like this:
when(mockStorageService.store(expectedQARecord)).thenReturn(101);
Now let's say that at the end of the test, you want to ensure that the method of QAService that you're testing will absolutely call storageService.delete(101). A Mockito mockStorageService would check that like this:
verify(mockStorageService).delete(101);
It is often unnecessary to verify statements you have made with when, because the test is unlikely to succeed unless the system under test calls the mock correctly to get that return value (101 here).
Now let's say that you've written another block of code called QAApplication, which you're testing in a unit test called QAApplicationTest, that depends on QAService. You may not have QAService finished or tested, and using a real QAService would require a StorageService, so instead you use mock QAService with a real QAApplication in your unit test called QAApplicationTest.
So, to sum up, a mock works within unit tests to mock the dependencies of the system under test. In your situation, QAServiceTest will not need a mock QAService, but may be used to mock the dependencies of QAService. If you do need a mock QAService, you'll need it when testing another class where QAService itself is a dependency.

What's the best way to unit test classes that delegate the work to others?

I have a question about how best to tackle JUnit testing of a top level class. Imagine I have a class, SomeWriter, that has a method that reformats a String and writes it to a stream. The method doesn't actually do the work but instead delegates it to a member object that actually does the real work. I've summarised this in the class below.
public class SomeWriter {
public void writeReformattedDataToStream(OutputStream outStream, String message) {
myReformatter.DoTheActualWorkAndWriteDataToStream(outStream, message);
}
}
Now in this hypothetical example, I've already written my unit tests for the myReformatter class and I've demonstrated that myReformatter works. My question is, how should I tackle the unit testing of the writeReformattedDataToStream in SomeWriter?
If I were black box testing, I would need to write the same test as I applied to the myReformatter class because I wouldn't know how it implements the task. However, unit testing is really white box testing, so is it valid for the test merely to ensure that myReformatter is being correctly called?
The bottom line is should my test of writeReformattedDataToStream effectively repeat the test of myReformatter, or mock myReformatter and just check it's being called correctly?
I appreciated this is similar to JUnit Test - Class invokes methods in other class
Immediate delegation like this usually falls under the heading of "too simple to test", but if you have some absolute requirement for it, then you need to mock your OutputStream (using EasyMock or a similar tool) and myReformatter and verify that the delegate calls the appropriate method.
As chrylis says, you should not test this method.
There is actually nothing to test.
If you write a test case that tests that the delegate / service is called, then your test is bound to the implementation of the tested method.
So any change in the implementation of the method would require to change the test; and I am sure that you do not want that.
Try injection. For testing purposes you could inject your own implementation of the myReformater class that simply checks that the method was called correctly and returns. Then you are testing your test class in isolation.

Categories

Resources