问题
I am trying to Test a method but it has a global variable which is null, Please guide me so I can assign value to global variable i.e. a Map
My Junit:
public class ErrorTest {
@Mock
private DataSource db;
@Mock
private JdbcTemplate jdbcTemplate;
@InjectMocks
private RateServiceImpl rateService = new RateServiceImpl();
@Mock
private RaterDao raterDao;
@Resource
private MessageSource msg ;
@Mock
Map<String, StringAttribute> errorMap = new HashMap<String, StringAttribute>();
@Before
public void setup() throws IOException, InterruptedException {
MockitoAnnotations.initMocks(this);
MockMvcBuilders.standaloneSetup(rateService).build();
}
@Test
public void findAllErrors() throws Exception {
String error;
List<Error> erList = new ArrayList<>();
Error er27 = new ErrorImpl("27",
"No detail found",
"Please enter detail.");
erList.add(er27);
Error er22 = new ErrorImpl("1",
"Maximum number exceeded",
"Please contact Technical Support.");
erList.add(er22);
for (int index = 0; index < erList.size(); index++) {
StringAttribute st = new StringAttributeImpl();
st.setName(erList.get(index).getDescription());
st.setValue(erList.get(index).getResolution());
errorMap.put(erList.get(index).getCode(), st);
}
List<Error> errorList = raterDao.findAllErrors();
assertThat(errorList, is(notNullValue()));
StringAttribute map27 = errorMap.get("27");
Mockito.when(rateService.findRwxlClientError("27")).thenReturn(map27);
StringAttribute map22 = errorMap.get("22");
Mockito.when(rateService.findRwxlClientError("22")).thenReturn(map22);
assertTrue("ParseShipment failed", map27.getName().equals("No detail found"));
assertTrue("ParseShipment failed", map22.getName().equals("Please contact Technical Support."));
}
}
My Main Class:
@Service
public class RateServiceImpl implements RateService {
protected final Log logger = LogFactory.getLog(getClass());
@Autowired
private RaterDao raterDao;
private Map<String, StringAttribute> errorMap = new HashMap<String, StringAttribute>();
@Resource
private MessageSource msg;
@PostConstruct
public void init() throws Exception {
**errorMap** = findAllClientErrors();
}
public Map<String, StringAttribute> findAllClientErrors() throws Exception {
List<Error> errorList = raterDao.findAllClientErrors();
for (int index = 0; index < errorList.size(); index++) {
StringAttribute st = new StringAttributeImpl();
st.setName(errorList.get(index).getDescription());
st.setValue(errorList.get(index).getResolution());
errorMap.put(errorList.get(index).getCode(), st);
}
return errorMap;
}
@Override
public StringAttribute findClientError(String code) throws Exception {
StringAttribute error = new StringAttributeImpl();
if (code.equals(Constants.ERROR_CODE_SETTING_UNAVAILABLE)) {
error.setName(msg.getMessage("SETTING.MESSAGE.ERROR", null,null));
error.setValue(msg.getMessage("SETTING.MESSAGE.RESOLUTION", null,null));
return error;
}
StringAttribute map = errorMap.get(code);
if (map == null || map.getName().isEmpty()) {
error.setName(msg.getMessage("DEFAULT.MESSAGE", new Object[] { code }, null));
error.setValue("");
} else {
error.setName(errorMap.get(code).getName());
error.setValue(errorMap.get(code).getValue());
}
return error;
}
}
I tried multiple solution but doesn't work, some time map becomes empty or null. Any solution works which pass my test case. I want to test findClientError(String code) and the issue is with errorMap
回答1:
So, you can use ReflectionUtils.setField method. I made a small example, it is not exactly like your code, but overall you will get the idea.
So here's my class under test. Doing almost exactly like your example. I have hello
method just to test and check if it is working or not.
class RateService {
private static Map<String, Object> errorMap = new HashMap<>();
@PostConstruct
public void init () {
this.errorMap = findAllErrors();
}
private Map<String, Object> findAllErrors() {
Map<String, Object> errorMap = new HashMap<>();
errorMap.put("a", new Object());
errorMap.put("b", new Object());
errorMap.put("c", new Object());
return errorMap;
}
// a method for demo purposes
public String hello() {
if (errorMap.size() > 0) {
return String.join(",", errorMap.keySet());
} else {
return "Empty";
}
}
}
Here's my test class. The third argument of the setField
method is the object that is going to be set in that field. So, you can create a mock, or real object there. I assigned a real object with dummy values. Then tested against that.
class MainTest {
private RateService rateService;
@BeforeEach
void setUp() {
this.rateService = new RateService();
}
private Map<String, Object> exampleErrorObjects() {
Map<String, Object> errorMap = new HashMap<>();
errorMap.put("x", new Object());
errorMap.put("y", new Object());
errorMap.put("z", new Object());
return errorMap;
}
@Test
void testHello() {
// given:
ReflectionTestUtils.setField(RateService.class, "errorMap", exampleErrorObjects());
// when:
final String result = this.rateService.hello();
// then:
assertEquals("x,y,z", result);
}
}
I am setting the static field in a test method because you may want your class to be in different states (based on the errorMap
field) in each test.
来源:https://stackoverflow.com/questions/62412058/junit-mockito-for-global-java-util-map