0

I dont have alot of experience mock testing.

I wrote a service to load codes from a property file. This works fine. Now I would like to write unit tests for this service, but somehow it is not working, what is wrong and how to fix it? below my service class + unit test class and property file.

public class PhoneCodeService {

private static final Logger LOG = LoggerFactory.getLogger(PhoneCodeService.class);
private static final String PROPERTY_FILE_NAME = "phone-code.properties";
private final Map<String, String> phoneCodes;
private final Properties properties = new Properties();

/**
 * Default constructor
 */
public PhoneCodeService() {
    try {
        readPhoneCodesFromPropertyFile();
    } catch (IOException e) {
        LOG.debug("Could not read property file " + PROPERTY_FILE_NAME);
    }
      Map<String, String> map = new HashMap<String, String>();
        for (String key : properties.stringPropertyNames()) {
            map.put(key, properties.getProperty(key));
        }
        phoneCodes = map;
    }


public String getPhonecode(final String input) {
        String code = phoneCodes.get(input);
        return code;
}

private void readPhoneCodesFromPropertyFile() throws IOException {
    InputStream inputStream = null;
    try {
        inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(PROPERTY_FILE_NAME);
        if (inputStream == null) {
            throw new FileNotFoundException("property file is missing");
        }
        properties.load(inputStream);
    } finally {
        IOUtils.closeQuietly(inputStream);
    }
}

}

Unit test class

public class PhoneCodeServiceTest {

@Mock
private PhoneCodeService phoneCodeService;

@Before
public void setUp() {
    initMocks(this);
    when(phoneCodeService.getPhonecode("86101")).thenReturn("984");
}

@Test
public void testNull() {
    assertEquals(null, phoneCodeService.getPhonecode(null));
}

@Test
public void testCodes() {
    final String[] CODES = {"86101"};
    for (String code : CODES) {
        assertEquals("984", phoneCodeService.getPhonecode(code));
    }
}

}

Example of my property file

000=1
001=2
002=3
003=4
004=5
user3122166
  • 81
  • 4
  • 10
  • What problem do you have? Tests work for me. – Ivan Jan 19 '18 at 16:00
  • Accoording to sonar the coverage of this code is zero – user3122166 Jan 19 '18 at 16:05
  • Yes, because the only thing that you are testing is the `getPhonecode` method, whcih actually is the one that you are mocking so no real code is covered. I would mock the Property object or even the InputStream (https://stackoverflow.com/questions/6371379/mocking-java-inputstream). – Ivan Jan 19 '18 at 16:15

1 Answers1

0

I'm a bit surprised. From your code it feels more like you're testing the Mock framework than your code. Nothing in your code is executed

In this case a more traditional testing approach would be more beneficial.

Create a test resource file named phone-code.properties containing test values This file must be available in your classpath during test

And test PhoneCodeService without mocking it

Then test it as follow:

public class PhoneCodeServiceTest {

@Test
public void testNull() {
    PhoneCodeService phoneCodeService = new PhoneCodeService();
    assertEquals(null, phoneCodeService.getPhonecode(null));
}

@Test
public void testCodes() {
    PhoneCodeService phoneCodeService = new PhoneCodeService();
    final String[] CODES = {"86101"};
    for (String code : CODES) {
        assertEquals("984", phoneCodeService.getPhonecode(code));
    }
}

For a 100% code coverage, your class need a way to provide an non existing file to PhoneCodeService

Mumrah81
  • 2,034
  • 2
  • 16
  • 23
  • 1
    I didn't request you to show us the content of a property file. I was advising you to create a file in src/test/resources named phone-code.properties containing the data you shown us and test PhoneCodeService without mocking it – Mumrah81 Jan 19 '18 at 16:19
  • I did that in my project, the properties loaded and the code works fine. My question is how to write unit test for it – user3122166 Jan 19 '18 at 16:31
  • First think about what you expect your algorithm to do, then write a test that tests for that behaviour, implement the behaviour so that it satisfies your test scenario and then clean up the tests and business code ;) http://blog.cleancoder.com/uncle-bob/2014/12/17/TheCyclesOfTDD.html – Samarek Jan 19 '18 at 16:33
  • If you did that in your project, why not doing it again in your test project? – Mumrah81 Jan 19 '18 at 16:43
  • Ok I will put the property file there but how to test it? Do you an example? – user3122166 Jan 19 '18 at 16:45