Junit Mockito for global java.util.Map

为君一笑 提交于 2020-06-17 09:40:29

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!