I'm creating the processor to collect data and provide them in list. But when I'm trying to create test for my method i'm catching assertionerror. What am I doing wrong?
My Class:
#AllArgsConstructor
public class ZteProcessor implements OurProcessor {
private final static String VENDOR = "ZTE";
private String jsonString;
private Map<String, String> metricsGU;
private Map<String, String> metricsUMTS;
private Map<String, String> metricsLTE;
#Override
public List<TimingAdvance> getTA() throws ParseException, NotFoundPatternOrMetricsException {
TimeAdvanceDataStore data = new TimeAdvanceDataStore();
AllDataFromJSONFile fromJSONFile = ProcessorUtil.getAllData(jsonString);
if (jsonString.contains("String")) {
return data.allDataToTimingAdvance(VENDOR, fromJSONFile, metricsGU, 2);
} else if (jsonString.contains("String-2")) {
return data.allDataToTimingAdvance(VENDOR, fromJSONFile, metricsUMTS, 3);
} else if (jsonString.contains("String3")) {
return data.allDataToTimingAdvance(VENDOR, fromJSONFile, metricsLTE, 4);
} else {
throw new NotFoundPatternOrMetricsException();
}
}
}
My Test:
#RunWith(PowerMockRunner.class)
#PrepareForTest({ProcessorUtil.class})
public class ZteProcessorTest {
#Mock
private AllDataFromJSONFile fromJSONFile;
#Mock
private TimeAdvanceDataStore data;
private OurProcessor processor;
private TimingAdvance timingAdvance = new TimingAdvance();
private Map<String, String> metricsGU = new HashMap<>();
private Map<String, String> metricsUMTS = new HashMap<>();
private Map<String, String> metricsLTE = new HashMap<>();
#Test
public void getTATest() throws Exception {
String jsonString = " { String : value}";
processor = new ZteProcessor(jsonString, metricsGU, metricsUMTS, metricsLTE);
List<TimingAdvance> list = new ArrayList<>();
list.add(timingAdvance);
PowerMockito.mockStatic(ProcessorUtil.class);
when(ProcessorUtil.getAllData(jsonString)).thenReturn(fromJSONFile);
when(data.allDataToTimingAdvance(jsonString, fromJSONFile, metricsGU, 2)).thenReturn(list);
assertEquals(list, processor.getTA());
}
}
Stacktrace:
java.lang.AssertionError:
Expected :[TimingAdvance{filial='null', vendor='null', cellName='null', periodDate=null, taMetrics=null}]
Actual :[]
<Click to see difference>
at org.junit.Assert.fail(Assert.java:88)
at org.junit.Assert.failNotEquals(Assert.java:834)
at org.junit.Assert.assertEquals(Assert.java:118)
at org.junit.Assert.assertEquals(Assert.java:144)
My ZteProcessor using static method getAllData(jsonString) of class ProcessorUtill. And for it I use powermock.
The problem stems from the fact that you are setting your expectations on a TimeAdvanceDataStore data mock, but you are creating a new instance of TimeAdvanceDataStore in your method under test.
Since you are already using PowerMockito, you can tap into new object creation like
PowerMockito.whenNew(TimeAdvanceDataStore.class)
.withAnyArguments().thenReturn(data);
On top of that, think how many ZTEProcessors and TimeAdvanceDataStores you have in your app. Do you always want a new instance of TimeAdvanceDataStore in each call to getTA?
If not, just pass TimeAdvanceDataStore in a constructor.
If yes, common approaches when PowerMockito is not at your disposal are:
passing a factory of TimeAdvanceDataStore to ZTEProcessor constructor
passing TimeAdvanceDataStore to getTA method
extracting a method constructing TimeAdvanceDataStore and overriding it in test
Related
I have a class:
public final class Core {
private final Deque<Double> stack = new ArrayDeque<>();
private final HashMap<String, Double> values = new HashMap<>();
public Deque<Double> getStack() {
return stack;
}
public HashMap<String, Double> getValues() {
return values;
}
}
I need a Junit test for this getters, but I don't know how to write it correctly
You get each property and add something to their collection
Then get each property again and verify that what you added is still there
I have a class which has a method I want to test, but it calls a private method in the same class to get a Map value. I want to mock what the private method returns to the method I want to test.
import java.util.*;
public class ClassOne {
public List<String> getList(String exampleString) {
List<String> exampleList = null;
Map<String, String> exampleMap = getMap();
String exampleValue = exampleMap.get(exampleString);
// Does some stuff
exampleList = Arrays.asList(exampleValue.split(","));
return exampleList;
}
private Map<String, String> getMap(){
Map<String, String> exampleMap = new HashMap<>();
exampleMap.put("pre-defined String", "pre-defined String");
return exampleMap;
}
}
From what I can find- it seems like I want to use PowerMock, but I can't seem to figure it out.
A way to mock the return of the private method getMap() when it is called by the method getList.
You should be able to mock it using powermock
"Mocking of Private Methods Using PowerMock | Baeldung" https://www.baeldung.com/powermock-private-method
You will be able to return a call from private method provided its in the same class where the private method is
I have a class with static variable
#Data
public final class Code {
private static Map<String, List<String>> codesForType = new HashMap<String, List<String>>() {{
put("code1", Arrays.asList("AVDF", "WREQ", "AWER"));
put("code2", Arrays.asList("SHYT", "DWEA", "XSSS", "AQWE"));
}};
public static List<String> getCodesByType(String type) {
return codesForType.get(type);
}
}
with following api
#GetMapping("/codes")
public Code getCodeForType() {
return new Code();
}
This is giving exception with message No converter found for return value of type: class com.model.Code.
Tried making the member as public but still has the same issue.
It works when I remove static keyword from private static Map<String, List<String>> codesForType
I could be missing a basic understanding of static keyword.
You don't need to create a new object as your methods are static.
you can simply do this :
#GetMapping("/codes")
public List<String> getCodeForType() {
// replace type with something you will receive in your request.
return Code.getCodesByType(type);
}
I am new to JMockit. I have recently tried writing unit tests where I have to test a system method that takes an argument. Inside the method under test the argument instance chains multiple of its methods to return a Collection object.
The code below simulates the exact situation I am facing. I am using jmockit-1.9
The system under test
public class SystemUnderTest {
public void doSomething(Dependency dependency) {
List<String> list = dependency.getMap().get("some-key");
System.out.println("got list -> " + list);
}
}
Dependency class
public class Dependency {
private Map<String, List<String>> map;
public Map<String, List<String>> getMap() {
return map;
}
public void setMap(Map<String, List<String>> map) {
this.map = map;
}
}
Test
#Test
public void testDoSomething(
#Mocked Dependency dependency,
#Mocked Map<String, List<String>> map,
#Mocked List<String> list
) {
new NonStrictExpectations() {{
dependency.getMap(); result = map;
map.get(anyString); result = list; //exception occurs here
}};
SystemUnderTest sut = new SystemUnderTest();
sut.doSomething(dependency);
}
When I run the test, I get the following exception
java.lang.IllegalArgumentException: Invalid return value for method returning class java.util.HashMap
at this line
map.get(anyString); result = list;
As it can be clearly see, the return type of map.get() should be a List but it says that the method is returning a HashMap.
What am I doing wrong?
Any help would be appreciated;
I have the following class
public class One {
private Map<String, String> nodes = new HashMap<String, String>();
public void addNode(String node, String nodefield){
this.nodes.put(node, nodefield);
}
}
I want to write a test class to test the addNode method and have the following:
#RunWith(MockitoJUnitRunner.class)
public class OneTest {
#InjectMocks
private One one = new One();
#Mock
Map<String, String> nodes;
#Test
public void testAddNode(){
one.addNode("mockNode", "mockNodeField");
Mockito.verify(nodes).put("mockNode","mockNodeField");
}
}
which works. But I was wondering if there is a way to do it without using #InjectMocks like the following
public class OneTest {
private One one;
#Test
public void testAddNode(){
Map<String, String> nodes = Mockito.mock(Map.class);
one = Mockito.injectmocks(One.class, nodes); // or whatever equivalent methods are
one.addNode("mockNode", "mockNodeField");
Mockito.verify(nodes).put("mockNode","mockNodeField");
}
}
How about change the class by injecting the map as a dependency? This makes it easier to test and gives you the added benefit of being able to use an implementation of the Map interface, for example:
public class One {
private Map<String, String> nodes;
public One(Map<String, String> nodes) {
this.nodes = nodes;
}
public void addNode(String node, String nodefield){
this.nodes.put(node, nodefield);
}
}
Then to test:
Map mockMap = Mockito.mock(Map.class);
One one = new One(mockMap);
one.addNode("mockNode", "mockNodeField");
Mockito.verify(mockMap).put("mockNode","mockNodeField");
Okay I figured it out by using PowerMockito instead of normal Mockito.
public class OneTest {
private One one;
#Test
public void testAddNode(){
HashMap nodes = PowerMockito.mock(HashMap.class);
PowerMockito.whenNew(HashMap.class).withNoArguments().thenReturn(nodes);
One one = new One();
one.addNode("mockNode", "mockNodeField");
Mockito.verify(nodes).put("mockNode","mockNodeField");
}
}
However, I don't really know what PowerMockito does that Mockito doesn't do to make it work though.