array.length выбрасывает исключение NullPointerException в junit, но не при запуске приложения - PullRequest
1 голос
/ 06 марта 2020

У меня странная проблема. Я все еще новичок в кодировании, поэтому это может быть связано с моим неправильным пониманием природы массивов. Моя проблема заключается в следующем: я пытаюсь написать модульные тесты для некоторых массивов в моем приложении, в которых я вызываю arr.length, который затем генерирует NPE. Массивы инициализируются в конструкторе класса, так что это не проблема. Я попытался инициализировать их значениями в каждом индексе, чтобы увидеть, изменилось ли это что-нибудь, но это не так. Больше всего меня смущает то, что когда я вызываю arr.length в одном и том же массиве, когда просто запускаю приложение, я получаю значение.

Что-то в JUnit мне не хватает?

Тестируемый метод не завершен. Я был в середине написания этого, когда я начал встречаться с NPE, поэтому я так и не добрался до кода, который присваивает значения массиву. Вот тест и класс, который тестируется:

@Test
void testCFArray() throws IOException {
    WebReaderFilter adder = new WebReaderFilter();
    Stock stock = new Stock("INTC");
    stock.setProfile(adder.getStockDetails(stock.getTicker()));

// Этот вызов метода выдает NPE

    stock.setArrays(stock.getProfile());
    BigInteger[] arr = stock.getCashFlowArray();
    assertEquals(BigInteger.valueOf(33145000000L), arr[0]);
}

package companyValueModel;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.HashMap;

public class Stock {

    private String ticker;
    private BigDecimal currentPrice;

    private BigInteger[] freeCashFlow;
    private BigInteger[] cashFlow;
    private BigInteger[] debt;
    private BigDecimal[] divPerShare;

/*
 * Keys: [companyName], [EBITDA], [Enterprise Value], [description], [industry],
 * [yearHigh], [price], [Total shareholders equity], [Goodwill and Intangible
 * Assets], [Capital Expenditure], [sector], [yearLow], [marketCap], [Dividend
 * payments], [ticker], [Revenue Growth], [Cash and short-term investments],
 * [Net Income], [Revenue]
 * 
 * Array keys: [Long-term debt-1], [Free Cash Flow0], [Long-term debt-2],
 * [Long-term debt0], [Free Cash Flow-2], [Dividend per Share0], [Free Cash
 * Flow-1], [Dividend per Share-1], [Operating Cash Flow0], [Operating Cash
 * Flow-1], [Operating Cash Flow-2]
 * 
 * keys with numbers at the end represent (0) = this year, (-1) = year prior,
 * etc.
 */

    private HashMap<String, String> profile;

    public Stock(String ticker) {
        this.ticker = ticker;
    }

    public Stock(HashMap<String, String> profile) {
        this.profile = profile;
        this.ticker = profile.get("ticker");
        freeCashFlow = new BigInteger[3];
        cashFlow = new BigInteger[3];
        debt = new BigInteger[3];
        divPerShare = new BigDecimal[2];
    }

    public HashMap<String, String> getProfile() {
        return profile;
    }

    public void setProfile(HashMap<String, String> profile) {
        this.profile = profile;
    }

    public String getTicker() {
        return ticker;
    }

    public void setCurrentPrice(BigDecimal price) {
        currentPrice = price;
    }

    public BigDecimal getCurrentPrice() {
        return currentPrice;
    }

    public void setArrays(HashMap<String, String> profile) throws NumberFormatException {
        int j = 0;
//      this line throws the NPE.  It disappears if I replace cashFlow.length with 3

        for (int i = 0; i < cashFlow.length; i++) {

//          This line was to verify that the key existed (it does)

            System.out.println(profile.get("Operating Cash Flow" + j));

//          also as an aside if anybody could tell me whether I'm parsing this string properly to bigInt I would appreciate it.

            double flow = Double.parseDouble(profile.get("Operating Cash Flow" + j));
            BigInteger cf = BigInteger.valueOf((long) flow);
            j--;

// Here is where the assigning code would have gone

        }
    }

    public BigInteger[] getCashFlowArray() {
        return cashFlow;
    }

    public BigInteger[] getFreeCashFlowArray() {
        return freeCashFlow;
    }

    public BigInteger[] getDebtArray() {
        return debt;
    }

    public BigDecimal[] getDivPerShare() {
        return divPerShare;
    }
}

Мне пришло в голову, что я мог бы написать аналогичный метод с константами для модульного теста и использовать другой для программы, но это оставило бы этот метод без надлежащего модульного теста, который не щекочет мою фантазию. В конце концов, массивы могут не понадобиться, но я думаю, что они будут удобны позже. Я прошу углубить моё понимание, чтобы, если я снова столкнусь с этой проблемой, я знал, что нужно сделать.

1 Ответ

2 голосов
/ 06 марта 2020

Конструктор String-аргумент используется вами при создании объекта Stock в тестовом примере.

-> Инициализировать cashFlow в этом ..

public Stock(String ticker) {
    this.ticker = ticker;
    cashFlow = new BigInteger[3]; // add this
}

ИЛИ

-> Использовать другой конструктор аргумента HashMap при инициализации Stock объекта в тестовом случае.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...