0

I'm using the latest spring-boot-gradle-plugin 2.0 to write unit tests. Long story short, I wanted to write a unit test for the init() postConstruct in the following class:

@Service
public class UserIdService implements IUserIdService
{
    // Local store
    private Map<String, Map<String, String>> store = new TreeMap<>();

    @Autowired
    private ResourceLoader resourceLoader;

    private static final String CSV_FILE_LOCATION = "data/userid-data.csv";

    @PostConstruct
    public void init()
    {
        System.out.println("Loading data from CSV file to UserID Store...");
        int totalRecords = 0;
        Resource resource = resourceLoader.getResource("classpath:" + CSV_FILE_LOCATION);
        try
        {
            InputStream inputStream = resource.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
            Iterable<CSVRecord> records = CSVFormat.DEFAULT.parse(inputStreamReader);

            for (CSVRecord record : records)
            {
                totalRecords++;
                String number = record.get(0);
                String context = record.get(1);
                String name = record.get(2);

                number = PhoneNumberHelper.convertPhoneNumber(number);

                //add only valid numbers to store
                if(!number.equals(PhoneNumberHelper.INVALID_INPUT))
                {
                    add(new UserId(name, number, context));
                }
            }
        }
        catch (Exception e)
        {
            System.err.println("Can't load or parse CSV file: " + CSV_FILE_LOCATION);
        }
        System.out.println("Loaded total [ " + store.size() + " / " + totalRecords + " ] records.");
    }

    public boolean add(UserId record)
    {
        if (null == store.get(record.getNumber()))
        {
            Map<String, String> newContext = new TreeMap<>();
            newContext.put(record.getContext(), record.getName());
            store.put(record.getNumber(), newContext);
        }
        else
        {
            Map<String, String> currentContext = store.get(record.getNumber());
            if (currentContext.get(record.getContext()) == null)
            {
                currentContext.put(record.getContext(), record.getName());
            }
            else
            {
                //context already exists for the phone number, throw error
                System.err.println("Context already exists for the phone number: " + record.toString());
                return false;
            }

        }
        return true;
    }

    public List<UserId> get(String number)
    {
        List<UserId> result = new ArrayList<>();

        if (null != store.get(number))
        {
            Map<String, String> currentContext = store.get(number);
            for (Map.Entry<String, String> entry : currentContext.entrySet())
            {
                UserId record = new UserId(entry.getValue(), number, entry.getKey());
                result.add(record);
            }
        }
        return result;
    }

    public boolean contains(String number)
    {
        return store.containsKey(number);
    }

}

The test class I created looks like this:

    @SpringBootApplication
    public class UserIdServiceTest {

        @Autowired
        private UserIdService userIdService;

        @Test
        public void testInit() throws Exception {
            userIdService.init();
            // assert things here..
        }

        @Test
        public void testAdd() {
        }

        @Test
        public void testGet() {
        }

        @Test
        public void testContains() {
        }
    }

When I try to run it, the test fails with:

UserIdServiceTest > testInit FAILED java.lang.NullPointerException at UserIdServiceTest.testInit(UserIdServiceTest.java:21)

I've been at this for days. What am I missing? - I'd like to be able to create tests for the methods described, but no matter where I reference userIdService, I always get the same NullPointerException.

Thanks for looking.

maciekgt3
  • 9
  • 2
  • Don't you have to annotate your Test Class with `@RunWith(SpringRunner.class) @SpringBootTest` – Siraj K May 24 '18 at 20:05
  • Thanks. Unfortunately, it still won't run. I now get the following: 'Failed to load ApplicationContext java.lang.IllegalStateException: Failed to load ApplicationContext'. I've been going in circles for days. I tried hundreds of things and combinations. I'm ready to give up. – maciekgt3 May 24 '18 at 22:17

0 Answers0