I want to mock "source" when the method "ProductAdapterService.adapt" is called by other class.
How to deal that? I really tried a lot of ways. Please help me. I am a new guy.Thanks a lot!
public class ProductAdapterService {
private final SearchParameter parameter;
private List<Festival> festivals;
public ProductAdapterService(SearchParameter parameter) {
this.parameter = parameter;
}
public SingleProduct adapt(SearchHit hit, boolean bidding) {
//I want to mock "source", I don't want to use "hit.getSource()"
Map<String, Object> source = hit.getSource();
SingleProduct sp = new SingleProduct();
sp.setId(TypeConverter.toInt(source.get(FieldName.PRODUCT_ID)));
sp.setName(TypeConverter.toString(source.get(FieldName.NAME)));
sp.setPrice(this.price(source.get(FieldName.PRICE), source.get(FieldName.PRICE_MAP), source.get(FieldName.FIRST_START_CITIES)));
sp.setLevel(TypeConverter.toInt(source.get(FieldName.PRODUCT_LEVEL)));
sp.setDepartureCityId(this.departureCity(source.get(FieldName.DEPARTURE_CITY_ID), source.get(FieldName.FIRST_START_CITIES)));
sp.setSaleMode(TypeConverter.toString(source.get(FieldName.SALE_MODE)));
sp.setBrandName(this.providerBrandName(source.get(FieldName.PROVIDER_BRAND)));
sp.setSaleCount(TypeConverter.toInt(source.get(FieldName.MONTHLY_ORDER)));
sp.setCommentCount(TypeConverter.toInt(source.get(FieldName.COMMENT_COUNT)));
sp.setCommentScore(TypeConverter.toFloat(source.get(FieldName.COMMENT_SCORE)));
sp.setBuType(BuType.GT);
sp.setType(this.productType(source.get(FieldName.SEARCH_TAB_TYPE_SHOW), sp.getSaleMode()));
sp.setSaleout(this.saleout(source.get(FieldName.NON_SALEOUT_CITIES), sp.getDepartureCityId()));
if (!sp.isSaleout()) {
sp.setFestival(this.festival(source.get(FieldName.FESTIVAL_IDS)));
}
System.out.println("sp.getName(): " + sp.getName());
return sp;
}}
And below is my test code:
public class TabSearcherTest0 {
#Test
public void test() {
SearchParameter parameter = SearchParameter.create();
Ghost.begin();
parameter.getFiltered().setTab(TabType.ALL);
parameter.getPoi().setKeyword("Spa");
parameter.getClient().setTrace(TraceMode.MAIN);
Map<String, Object> mapMock = new HashMap<String, Object>();
mapMock.put("productgroupid", "12877");
mapMock.put("productid", "5539739");
mapMock.put("firststartcitys", "[1, 2]");
mapMock.put("nonsaleoutcities", "[1, 2]");
mapMock.put("productdiamondlevel", "4");
mapMock.put("commentcount", "0");
mapMock.put("price", "0.0");
mapMock.put("name", "TestName");
mapMock.put("searchtabtypeshow", "1");
mapMock.put("comment", "0.0");
mapMock.put("salemode", "S");
mapMock.put("providerbrandid", "999999");
mapMock.put("departurecityid", "2");
// how to inject the map?
// ???
SearchModel model = SearchContext.createContext(parameter).search();
Ghost.end();
System.out.println(model);
}}
You are getting "mocking" the wrong way. You only used it when you can not use the real class implementation; but you need to control how some object reacts to methods calls to it.
Your method to test looks like:
public SingleProduct adapt(SearchHit hit, boolean bidding) {
//I want to mock "source", I don't want to use "hit.getSource()"
Map<String, Object> source = hit.getSource();
Wrong: you want to make sure that hit.getSource() is used. Because your production code is using is; and you write your unit tests to text that code. So you want that your production code does its "normal" thing.
So, the very simply solution here is:
#Test
public void testAdapt() {
SearchHit mockedHit = mock(SearchHit.class);
Map<String, Object> resonseForGetSource = new HashMap<>();
resonseForGetSource.put("productgroupid", "12877");
...
doReturn(resonseForGetSource).when(mockedHit.getSource());
ProductAdapterService underTest = ...
underTest.adapt(mockedHit, true);
... probably some asserts
or something alike (don't nail me on the doReturn/when details here)
What you can see here: your production code needs that map to do its job; so you just make sure that such a map object shows up in your production code.
And in case it would be possible to use a real SearchHit object (that you could configure with such a map); then using that would even be better than mocking that object.
You absolutely try to minimize your usage of mocking. You only use it to gain control over objects that are used during a certain test.
And beyond that: you are not clear about the scope of your unit testing. In order to test that one method, you dont need no ghosts. The unit test code you are showing simply doesn't make sense in the context of the class you are showing us here! Thus: you better step back and carefully look into "which units do I have" and "how to unit test exactly that unit X". You don't text "X" by testing "Y"!
Related
Hello I am fairly new to unit testing with Junit as well as Mockito. I think I have a fairly reasonable understanding of the principles but I can't seem to find any explanations of what I am specifically trying to test online.
I want to test a method, that calls several other methods (void and non-void), which also instantiates objects in the method body. I unfortunately cannot share the code as it is not mine, but here is a general format:
class classToTest {
private final field_1;
public void methodToTest( string id, List object_1, List object_2) {
try {
Map<SomeObject_1, SomeObject_2> sampleMap = new HashMap<>();
method_1(object_1, object_2); //void function modifies object_2
field_1.method_2(id, object_2);
Map<SomObeject_1, List<object>> groupedList = groupList(object_2)
//Then some stuff is added to the sampleMap
}
//catch would be here
}
At the moment I only care about testing method_1, and I cannot test directly as it is a private method so I must go through this parent method call. I wish I could change the code but I have been asked to keep it the same and to test in this manner with Mockito and Junit.
I know I need to Mock an object of the class to Test as well as its parameter:
private classToTest classToTestObject;
#Mock private field_1 f1;
#Before
public void setup() {
MockitoAnnotations.init.Mocks(this);
classToTestObject = mock(classToTest.class, CALLS_REAL_METHODS);
}
but I don't know where to start my actual test, as in how I can essentially just execute that one method call and ignore all the rest. I can't just not ignore the other objects and method calls either as the main method will throw exceptions if they are not handled correctly.
Any help and guidance is much appreciated, sorry that I could not share the code. Thank You!
At the moment I only care about testing method_1, and I cannot test directly as it is a private method so I must go through this parent method call.
Per your comment, and the note in your code:
method_1(object_1, object_2); //void function modifies object_2
You would set up a test that allows you to verify the expected final state of object_2. You would do this with a real instance of the class, not a mock.
#Test
public void method1Test() {
// Assemble - your preconditions
ClassToTest subject = new ClassToTest();
List<SomeType> object_1 = new ArrayList();
List<SomeOtherType> object_2 = new ArrayList();
// Populate object_1 and object_2 with data to use as input
// that won't throw exceptions. Call any methods on subject that put
// it in the desired state
// Act - call the method that calls the method under test
subject.methodToTest("some id that makes the method run correctly", object_1, object_2);
// Assert - one or more assertions against the expected final state of object_2
assertThat(object_2).matchesYourExpectations();
}
So here is the thing, I found new Integer() in my code and which is deprecated now I planed to remove that pic of code (new Integer()) to Integer.valueOf() but as company rules I have to write the Junit for that change, I just need to verify that pic of code no need to write whole coverage of the method, Now I am getting confused, how I can do it.
Before:
#SuppressWarnings({ "rawtypes", "unchecked" })
public List getLogsByLcrErrorCodeInLast(String code, long period) throws Exception {
Object params = new ObjectPair(new Integer(code), new MesDbUtil(ibatis).getPastMesDbDate(period));
List mesdbLogs = client.queryForList("LcrLog.getLogsByLcrErrorCodeInLast", params);
Iterator mesdbLogsIter = mesdbLogs.iterator();
List results = new ArrayList();
while (mesdbLogsIter.hasNext()) {
MesDbLcrLog mesdbLog = (MesDbLcrLog) mesdbLogsIter.next();
results.add(mesdbLog.getLog());
}
return results;
}
After::
#SuppressWarnings({ "rawtypes", "unchecked" })
public List getLogsByLcrErrorCodeInLast(String code, long period) throws Exception {
Object params = new ObjectPair(Integer.valueOf(code), new MesDbUtil(ibatis).getPastMesDbDate(period));
List mesdbLogs = client.queryForList("LcrLog.getLogsByLcrErrorCodeInLast", params);
Iterator mesdbLogsIter = mesdbLogs.iterator();
List results = new ArrayList();
while (mesdbLogsIter.hasNext()) {
MesDbLcrLog mesdbLog = (MesDbLcrLog) mesdbLogsIter.next();
results.add(mesdbLog.getLog());
}
return results;
}
I tried to do like following, I don't know is it correct or not, and need to go for some professional way for it too because of code review;
public class integerValueOf(){
private Integer code=23;
#Test
public void testGetLogsByLcrErrorCodeInlast() throws Exception{
assertEquals(new Integer(code), Integer.valueOf(code));
}
}
Are you unit testing every other API in the JRE? No? Why would you unit test Integer.valueOf(...) then?
Your existing unit tests for getLogsByLcrErrorCodeInLast should cover the change in the integer instantiation. E.g. you have tests for different values of code and check that you get the expected params in client.queryForList(...).
If you don't have the tests, then you need to write them before you change the code.
Edit: I didn't even notice it earlier, but your production code converts a String to an Integer and your sugested unit test converts an Integer to an Integer. You're idea is fundamentally flawed because it doesn't test the code that you execute in production. It lets errors like this pass testing with green flags.
I have facade interface where users can ask for information about lets say Engineers. That information should be transferred as JSON of which we made a DTO for. Now keep in mind that I have multiple datasources that can provide an item to this list of DTO.
So I believe right now that I can use Decorative Pattern by adding handler of the datasource to the myEngineerListDTO of type List<EngineerDTO>. So by that I mean all the datasources have the same DTO.
This picture below shows that VerticalScrollbar and HorizontalScrollBar have different behaviours added. Which means they add behaviour to the WindowDecorator interface.
My question, does my situation fit the decorator pattern? Do I specifically need to add a behaviour to use this pattern? And is there another pattern that does fit my situation? I have already considered Chain of Responsibility pattern, but because I don't need to terminate my chain on any given moment, i thought maybe Decorator pattern would be better.
Edit:
My end result should be: List<EngineersDTO> from all datasources. The reason I want to add this pattern is so that I can easily add another datasource behind the rest of the "pipeline". This datasource, just like the others, will have addEngineersDTOToList method.
To further illustrate on how you can Chain-of-responsibility pattern I put together a small example. I believe you should be able to adapt this solution to suit the needs of your real world problem.
Problem Space
We have an unknown set of user requests which contain the name of properties to be retrieved. There are multiple datasources which each have varying amounts of properties. We want to search through all possible data sources until all of the properties from the request have been discovered. Some data types and data sources might look like bellow (note I am using Lombok for brevity):
#lombok.Data
class FooBarData {
private final String foo;
private final String bar;
}
#lombok.Data
class FizzBuzzData {
private final String fizz;
private final String buzz;
}
class FooBarService {
public FooBarData invoke() {
System.out.println("This is an expensive FooBar call");
return new FooBarData("FOO", "BAR");
}
}
class FizzBuzzService {
public FizzBuzzData invoke() {
System.out.println("This is an expensive FizzBuzz call");
return new FizzBuzzData("FIZZ", "BUZZ");
}
}
Our end user might require multiple ways to resolve the data. The following could be a valid user input and expected response:
// Input
"foobar", "foo", "fizz"
// Output
{
"foobar" : {
"foo" : "FOO",
"bar" : "BAR"
},
"foo" : "FOO",
"fizz" : "FIZZ"
}
A basic interface and simple concrete implementation for our property resolver might look like bellow:
interface PropertyResolver {
Map<String, Object> resolve(List<String> properties);
}
class UnknownResolver implements PropertyResolver {
#Override
public Map<String, Object> resolve(List<String> properties) {
Map<String, Object> result = new HashMap<>();
for (String property : properties) {
result.put(property, "Unknown");
}
return result;
}
}
Solution Space
Rather than using a normal "Decorator pattern", a better solution may be a "Chain-of-responsibility pattern". This pattern is similar to the decorator pattern, however, each link in the chain is allowed to either work on the item, ignore the item, or end the execution. This is helpful for deciding if a call needs to be made, or terminating the chain if the work is complete for the request. Another difference from the decorator pattern is that resolve will not be overriden by each of the concrete classes; our abstract class can call out to the sub class when required using abstract methods.
Back to the problem at hand... For each resolver we need two components. A way to fetch data from our remote service, and a way to extract all the required properties from the data retrieved. For fetching the data we can provide an abstract method. For extracting a property from the fetched data we can make a small interface and maintain a list of these extractors seeing as multiple properties can be pulled from a single piece of data:
interface PropertyExtractor<Data> {
Object extract(Data data);
}
abstract class PropertyResolverChain<Data> implements PropertyResolver {
private final Map<String, PropertyExtractor<Data>> extractors = new HashMap<>();
private final PropertyResolver successor;
protected PropertyResolverChain(PropertyResolver successor) {
this.successor = successor;
}
protected abstract Data getData();
protected final void setBinding(String property, PropertyExtractor<Data> extractor) {
extractors.put(property, extractor);
}
#Override
public Map<String, Object> resolve(List<String> properties) {
...
}
}
The basic idea for the resolve method is to first evaluate which properties can be fulfilled by this PropertyResolver instance. If there are eligible properties then we will fetch the data using getData. For each eligible property we extract the property value and add it to a result map. Each property which cannot be resolved, the successor will be requested to be resolve that property. If all properties are resolved the chain of execution will end.
#Override
public Map<String, Object> resolve(List<String> properties) {
Map<String, Object> result = new HashMap<>();
List<String> eligibleProperties = new ArrayList<>(properties);
eligibleProperties.retainAll(extractors.keySet());
if (!eligibleProperties.isEmpty()) {
Data data = getData();
for (String property : eligibleProperties) {
result.put(property, extractors.get(property).extract(data));
}
}
List<String> remainingProperties = new ArrayList<>(properties);
remainingProperties.removeAll(eligibleProperties);
if (!remainingProperties.isEmpty()) {
result.putAll(successor.resolve(remainingProperties));
}
return result;
}
Implementing Resolvers
When we go to implement a concrete class for PropertyResolverChain we will need to implement the getData method and also bind PropertyExtractor instances. These bindings can act as an adapter for the data returned by each service. This data can follow the same structure as the data returned by the service, or have a custom schema. Using the FooBarService from earlier as an example, our class could be implemented like bellow (note that we can have many bindings which result in the same data being returned).
class FooBarResolver extends PropertyResolverChain<FooBarData> {
private final FooBarService remoteService;
FooBarResolver(PropertyResolver successor, FooBarService remoteService) {
super(successor);
this.remoteService = remoteService;
// return the whole object
setBinding("foobar", data -> data);
// accept different spellings
setBinding("foo", data -> data.getFoo());
setBinding("bar", data -> data.getBar());
setBinding("FOO", data -> data.getFoo());
setBinding("__bar", data -> data.getBar());
// create new properties all together!!
setBinding("barfoo", data -> data.getBar() + data.getFoo());
}
#Override
protected FooBarData getData() {
return remoteService.invoke();
}
}
Example Usage
Putting it all together, we can invoke the Resolver chain as shown bellow. We can observe that the expensive getData method call is only performed once per Resolver only if the property is bound to the resolver, and that the user gets only the exact fields which they require:
PropertyResolver resolver =
new FizzBuzzResolver(
new FooBarResolver(
new UnknownResolver(),
new FooBarService()),
new FizzBuzzService());
Map<String, Object> result = resolver.resolve(Arrays.asList(
"foobar", "foo", "__bar", "barfoo", "invalid", "fizz"));
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
System.out.println(mapper
.writerWithDefaultPrettyPrinter()
.writeValueAsString(result));
Output
This is an expensive FizzBuzz call
This is an expensive FooBar call
{
"foobar" : {
"foo" : "FOO",
"bar" : "BAR"
},
"__bar" : "BAR",
"barfoo" : "BARFOO",
"foo" : "FOO",
"invalid" : "Unknown",
"fizz" : "FIZZ"
}
We are working with mvc design pattern, where all the data is stored under map.
I want to iterate over all the classes in the system and for each to check what the method is putting on the map and what does the method get from the map.
For example for the next code:
private void myFunc()
{
Object obj = model.get("mykey");
Object obj2 = model.get("mykey2");
.....
model.put("mykey3", "aaa");
}
I want to know that in this function we have 2 gets: mykey and mykey2 and 1 put: mykey3
How can I do it with the code.
Thanks.
You tagged this with "reflection", but that will not work. Reflection only allows you to inspect "signatures". You can use it to identify the methods of a class, and the arguments of the methods.
It absolutely doesn't help you to identify what each method is doing.
In order to find out about that, you would need to either parse the java source code side, or byte code classes. As in: write code that reads that content, and understands "enough" of it to find such places. Which is a very challenging effort. And of course: it is very easy to bypass all such "scanner" code, by doing things such as:
List<String> keysToUpdate = Arrays.asList("key1", "key2");
for (String key : keysToUpdate) {
... does something about each key
Bang. How would you ever write code that reliable finds the keys for that?
When you found that code, now imagine that the list isn't instantiated there, but far away, and past as argument? When you figured how to solve that, now consider code that uses reflection to acquire the model object, and calls method on that. See? For any "scanner" that you write down, there will be ways to make that fail.
Thus the real answer is that you are already going down the wrong rabbit hole:
You should never have written:
Object obj = model.get("mykey");
but something like
Object obj = model.get(SOME_CONSTANT_FOR_KEY_X);
Meaning: there is no good way to control such stuff. The best you can do is to make sure that all keys are constants, coming from a central place. Because then you can at least go in, and for each key in that list of constants, you can have your IDE tell you about their usage.
NOTES
I assumed that your situation is complicated enough that simple or advanced text search in codebase doesn't help you.
This is a hack not a generic solution, designed only for testing and diagnosis purposes.
To use this hack, you must be able to change your code and replace the actual model with the proxy instance while you're testing/diagnosing. If you can't do this, then you have to use an even more advanced hack, i.e. byte-code engineering with BCEL, ASM, etc.
Dynamic proxies have drawbacks on code performance, therefore not an ideal choice for production mode.
Using map for storing model is not a good idea. Instead a well-defined type system, i.e. Java classes, should be used.
A general design pattern for a problem like this is proxy. An intermediate object between your actual model and the caller that can intercept the calls, collect statistics, or even interfere with the original call. The proxied model ultimately sends everything to the actual model.
An obvious proxy is to simply wrap the actual model into another map, e.g.
public class MapProxy<K, V> implements Map<K, V> {
public MapProxy(final Map<K, V> actual) {
}
// implement ALL methods and redirect them to the actual model
}
Now, reflection doesn't help you with this directly, but can help with implementing a proxy faster using dynamic proxies (Dynamic Proxy Classes), e.g.
#SuppressWarnings("unchecked")
private Map<String, Object> proxy(final Map<String, Object> model) {
final InvocationHandler handler = new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// Collect usage stats or intervene
return method.invoke(model, args);
}
};
return (Map<String, Object>) Proxy.newProxyInstance(Map.class.getClassLoader(),
new Class<?>[] { Map.class }, handler);
}
NOTE: Either case you need to be able to replace the actual model with the proxied model at least for the duration of your test.
With another trick, you can find out who called which method of your model. Simply by accessing Thread.currentThread().getStackTrace() and retrieving the appropriate element.
Now puting all the pieces together:
InvocationLog.java
public final class InvocationLog {
private Method method;
private Object[] arguments;
private StackTraceElement caller;
public InvocationLog(Method method, Object[] arguments, StackTraceElement caller) {
this.method = method;
this.arguments = arguments;
this.caller = caller;
}
public Method getMethod() { return this.method; }
public Object[] getArguments() { return this.arguments; }
public StackTraceElement getCaller() { return this.caller; }
#Override
public String toString() {
return String.format("%s (%s): %s",
method == null ? "<init>" : method.getName(),
arguments == null ? "" : Arrays.toString(arguments),
caller == null ? "" : caller.toString());
}
}
ModelWatch.java
public final class ModelWatch {
private final Map<String, Object> modelProxy;
private final List<InvocationLog> logs = new ArrayList<>();
public ModelWatch(final Map<String, Object> model) {
modelProxy = proxy(model);
}
#SuppressWarnings("unchecked")
private Map<String, Object> proxy(final Map<String, Object> model) {
final InvocationHandler handler = new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
log(method, args, Thread.currentThread().getStackTrace());
return method.invoke(model, args);
}
};
return (Map<String, Object>) Proxy.newProxyInstance(Map.class.getClassLoader(),
new Class<?>[] { Map.class }, handler);
}
private void log(Method method, Object[] arguments, StackTraceElement[] stack) {
logs.add(new InvocationLog(method, arguments, stack[3]));
// 0: Thread.getStackTrace
// 1: InvocationHandler.invoke
// 2: <Proxy>
// 3: <Caller>
}
public Map<String, Object> getModelProxy() { return modelProxy; }
public List<InvocationLog> getLogs() { return logs; }
}
To put it in use:
private Map<String, Object> actualModel = new HashMap<String, Object>();
private ModelWatch modelWatch = new ModelWatch(model);
private Map<String, Object> model = modelWatch.getModelProxy();
// Calls to model ...
modelWatch.getLogs() // Retrieve model activity
How do I call populateMapWithFormattedDates method in JUnit and how to write JUnit populateMapWithFormattedDates for this method. I dont know how to write JUnit for nested methods so kindly help.
protected Map<String, String> populateDispatch(final RequestDispatchData requestDispatchData)
{
final Map<String, String> map = getDispatchFieldMapper().populateMapper(requestDispatchData);
populateMapWithFormattedDates(requestDispatchData, map);
}
private void populateMapWithFormattedDates(final RequestDispatchData requestDispatchData, final Map<String, String> map)
{
String dateFormatted = map.get("ticket_date");
Date date = null;
try
{
date = new SimpleDateFormat("MM/dd/yy").parse(dateFormatted);
}
catch (ParseException parseException)
{
customLogger.logMessage(diagnosticMethodSignature, DiagnosticType.EXCEPTION,
"Exception in parsing start date of ticket " + parseException);
}
map.put("startDateDDMMYY", DateEnum.DDMMYY.getFormattor().format(date));
map.put("startDateDDMMMYY", DateEnum.DDMMMYY.getFormattor().format(date));
map.put("startDateDMY", DateEnum.DMY.getFormattor().format(date));
map.put("startDateYYMMDD", DateEnum.YYMMDD.getFormattor().format(date));
}
Simple: you don't test private methods directly.
Instead, you focus on the "public contract" of those methods that get invoked "from the outside". In your case, that would be:
Map<String, String> populateDispatch(...
Thus you want write tests like:
#Test
public void populateDispatchForValidDate() {
RequestDispatchData request = ...
Map<String, String> actualOutput = underTest.populateDispatch(request);
assertThat(actualOutput.size(), is(5));
}
The above is just meant as an example. What it does:
create a "request" object. This could be a mock; or a real object - depends on what exactly your various methods are doing with this object. And how easy it is to create a "real" RequestDispatchData object with "test data"
it invokes that method under test
it asserts one/several properties of the result coming back
Looking at your production code, that code is doing way too many things within that single method. You might want to read about "clean code" and improve that code. That probably lead to the creation of some helper classes which would be easier to test then.
There is nothing such as a nested method in Java. It's a nested function call is what it is. Plus, yea, you cannot call the private functions of a class through its object so testing them individually by calling them is not possible.
You can although have a public or protected function doing the call somewhat like a getter.
I believe your code is some what like,
protected Map<String, String> populateDispatch(final RequestDispatchData requestDispatchData)
{
final Map<String, String> map = getDispatchFieldMapper().populateMapper(requestDispatchData);
return populateMapWithFormattedDates(requestDispatchData, map);
}
note that you have missed the return statement, and update the map on certain condition from ,
private void populateMapWithFormattedDates(final RequestDispatchData requestDispatchData, final Map<String, String> map)
{
// Map manipulation here
}
So if you have minimum dependency on the getDispatchFieldMapper().populateMapper(), then you can directly invoke populateDispatch() from your test code, else you may have to find a way to inject a custom implementation of DispatchFieldMapper to prepare the map for testing your target method.
Injection of DispatchFieldMapper can be via overriding the getDispatchFieldMapper() or use a setDispatchFieldMapper() on your class.
While preparing your custom DispatchFieldMapper, make sure the populateMapper() returns a map with all data required for your testing.
It is not good idea to call non accessible method while testing directly form the test class.
Second thing : Non accessible method is always called form some accessible method or scope otherwise that code is dead code just remove that.
Because method is privet, so if it is in use then it called somewhere from code of current class. in your code it called form populateDispatch, so actual way to write test case for populateMapWithFormattedDates method is cover all the scenarios for populateDispatch method and populateDispatch is also used form sub class of the current class call it form there.
But you can call private method in junit like:
Deencapsulation.invoke(<object of class in called method is exist>, "populateMapWithFormattedDates", <object of RequestDispatchData class>, <object of Map<String, String> class>);
Again it is a way to call private method but you should not use this...
You should decouple the populateMapWithFormattedDates method like this:
// I created an utility class but it's a suggestion.
// I'm using an util class because you don't use requestDispatchData for
// anything. But if you do, maybe it's a good idea to implement this code
// on RequestDispatchData class
class DispatchMapUtils {
// Note that I took of the requestDispatchData
public static Map<String, String> populateMapWithFormattedDates(final Map<String, String> map) throws ParseException {
// Your code without try-catch.
// Throw the exception to the caller of this method
// and try-catch there to use the customLogger
}
}
With this code, your test would be something like this:
#Test
public void shouldFormatTicketDateInVariousFormat() {
Map<String, String> map;
// Instantiate and put some initial datas
map = new ...
map.put('ticket_date') = ..
// Call the method!
DispatchMapUtils.populateMapWithFormattedDates(map);
// Do the assertions!
Assert.assertTrue(map.get("startDateDDMMYY").equals(...));
}
#Test
public void shouldThrowExceptionWhenTicketDateIsInvalid() {
// More testing code
}