При запуске теста выскакивает NullPointerException

127
13 июля 2021, 23:50

Приложение выполняет деление в столбик и выводит весь процесс в консоль. все работает, тесты проходит, проблема в том что при запуске теста выбивает NullPointerException. Не могу понять где и как с этим бороться. NPE выскакивает в предпоследней строке кода теста(String actual = subject.divide(256, 8);). Вот такой NPE:

`java.lang.NullPointerException
`at DivisionServiceTest.divide(DivisionServiceTest.java:30)
`at java.base/java.util.ArrayList.forEach(ArrayList.java:1380)
`at java.base/java.util.ArrayList.forEach(ArrayList.java:1380)

Вот код:

public class Division implements DivisionService {
private StringBuilder result = new StringBuilder();
private StringBuilder quotient = new StringBuilder();
private StringBuilder reminder = new StringBuilder();
public String divide(long dividend, long divider) throws IllegalArgumentException {
    if (divider == 0) {
        return "Divider cannot be 0, division by zero";
    }
    long absDividend = Math.abs(dividend);
    long absDivider = Math.abs(divider);
    if (absDividend < absDivider) {
        return "Dividend less than divider. Column Division isn't possible";
    }
    String[] dividentAsArray = String.valueOf(absDividend).split("");
    Integer reminderAsDigit;
    long multiplyResult;
    Integer dividerDigit = calculateDigit(absDivider);
    long mod;
    for (int i = 0; i < dividentAsArray.length; i++) {
        reminder.append(dividentAsArray[i]);
        reminderAsDigit = Integer.parseInt(reminder.toString());
        if (reminderAsDigit >= absDivider) {
            mod = reminderAsDigit % absDivider;
            multiplyResult = reminderAsDigit / absDivider * absDivider;
            String lastReminder = String.format("%" + (i + 2) + "s", "_" + reminderAsDigit.toString());
            result.append(lastReminder).append("\n");
            String multiply = String.format("%" + (i + 2) + "d", multiplyResult);
            result.append(multiply).append("\n");
            Integer tab = lastReminder.length() - calculateDigit(multiplyResult);
            result.append(makeDivider(reminderAsDigit, tab)).append("\n");
            quotient.append(reminderAsDigit / absDivider);
            reminder.replace(0, reminder.length(), Long.toString(mod));
            reminderAsDigit = Integer.parseInt(reminder.toString());
        } else {
            if (i >= dividerDigit) {
                quotient.append(0);
            }
        }
        if (i == dividentAsArray.length - 1) {
            result.append(String.format("%" + (i + 2) + "s", reminderAsDigit.toString())).append("\n");
        }
    }
    modifyResultToView(absDividend, absDivider);
    if (dividend > 0 && divider < 0) {
        result.insert(0, "-");
        return result.toString();
    }
    if (dividend < 0 && divider > 0) {
        result.insert(0, "-");
        return result.toString();
    } else return result.toString();
}
private String makeDivider(Integer reminderNumber, Integer tab) {
    return assemblyString(tab, ' ') + assemblyString(calculateDigit(reminderNumber), '-');
}
private void modifyResultToView(long dividend, long divider) {
    int[] index = new int[3];
    for (int i = 0, j = 0; i < result.length(); i++) {
        if (result.charAt(i) == '\n') {
            index[j] = i;
            j++;
        }
        if (j == 3) {
            break;
        }
    }
    int tab = calculateDigit(dividend) + 1 - index[0];
    result.insert(index[2], assemblyString(tab, ' ') + "│" + quotient.toString());
    result.insert(index[1], assemblyString(tab, ' ') + "│" + assemblyString(quotient.length(), '-'));
    result.insert(index[0], "│" + divider);
    result.replace(1, index[0], Long.toString(dividend));
}
private int calculateDigit(long i) {
    return (int) Math.log10(i) + 1;
}
private String assemblyString(int numberOfSymbols, char symbol) {
    StringBuilder string = new StringBuilder();
    for (int i = 0; i < numberOfSymbols; i++) {
        string.append(symbol);
    }
    return string.toString();
}
}

Вот тест:

import org.junit.Before;
import org.junit.jupiter.api.Test;
import static org.junit.Assert.assertEquals;
public class DivisionServiceTest {`введите сюда код`
private DivisionService subject;
@Before
public void initSubject() throws Exception {
    subject = new Division();
}
@Test
public void divide() {
        /* Given */
        String expected =
                " 256 | 8\n" +
                        "-    |---\n" +
                        " 24  | 32\n" +
                        " --\n" +
                        " _16\n" +
                        "  16\n" +
                        "  --\n" +
                        "   0\n";
        /* When */
        String actual = subject.divide(256, 8);
        /* Then */
        assertEquals(expected, actual);
}
}
Answer 1

Похоже, что у вас несколько разных версий Junit в проекте и аннотация @Before не отрабатывает. Попробуйте оставить одну версию Junit. (я проверил на версии Junit 4.11 - ваш код работает без исключений).

PS: Если уже вы пробовали явно внутри тестового метода создать объект через new Division() в обход метода initSubject(), напишите, какой стек-трейс ошибки в этом случае.