如何在节点中解决"Cannot read property of undefined".js



我是JS中的新手,我需要为测试数据创建简单的CSV解析器。我有一个非常奇怪的问题。

这是我测试的代码:

'use strict';
const assert = require('assert');
const HomePage = require('../pages/HomePage');
const csv = require('../tools/CsvReader');
describe('Check if values are correct', () => {
    let dataProvider = csv.readFromCsv("test/resources/places.csv");
    function valuesTest(city, expectedLat, expectedLong) {
        it('Data must match', () => {
            let searchPlace = HomePage
                .open()
                .findByPlaceName(city)
                .getSearchPlace();
            assert.strictEqual(searchPlace.getLatitude(), expectedLat);
            assert.strictEqual(searchPlace.getLongtitude(), expectedLong);
            console.log(dataProvider[0].CITY);
        });
    }
    for (let i = 0; i < dataProvider.length; i++) {
        valuesTest(dataProvider[i].CITY, dataProvider[i].LAT, dataProvider[i].LONG)
    }
});

和我的CSV-Reader的代码:

'use strict';
const csv = require('csv-parser');
const fs = require('fs');
class CsvReader {

    readFromCsv(path) {
        let results = [];
        fs.createReadStream(path)
            .pipe(csv())
            .on('data', (data) => results.push(data));
        return results;
    }
}
module.exports = new CsvReader();

这是我的CSV:

CITY,LAT,LONG
Kyiv,50.447731,30.542721
Lviv,49.839684,24.029716
Ivano-Frankivsk,48.922634,24.711117

问题如下:为什么我可以在" valuest"块中使用变量" dataprovider",并且它可以正常工作并返回城市变量的值,而在" for" for" for" loop中,我无法使用它(可变的" dataprovider","城市"等不可用(,尽管它们位于同一块"描述"。

您的CSV阅读器是一个异步操作。我怀疑您的循环甚至在解析CSV之前就被执行并返回值。尝试将您的for循环置于函数中,并将其传递到readfromcsv函数作为回调。在数据事件上调用此功能,您将一定要获取数据。

您应该将回调传递给readFromCsv,该回调将在createReadStream完成后执行。您可以通过收听其end事件来确定createReadStream何时完成。(例如,请参见CSV-Parser示例代码(。

在您的情况下,您可以做类似的事情:

readFromCsv(path, onEnd) {
    let results = [];
    fs.createReadStream(path)
        .pipe(csv())
        .on('data', (data) => results.push(data))
        .on('end', () => onEnd(results));
}
csv.readFromCsv("test/resources/places.csv", function onData(data) {
    for (let i = 0; i < data.length; i++) {
        valuesTest(data[i].CITY, data[i].LAT, data[i].LONG);
    } 
});

您应该使用end事件而不是data事件来确定流何时完成。如果您在第一个data事件之后返回,则可能无法获取所有数据。

data事件是每个数据块发射一次。如果您的数据具有多个"块",则如果您在数据回调中返回,则将其截断。有关不同事件类型的详细信息,请参见Nodejs文档。您可能不会注意到小型测试文件有所不同,但要做一个更大的文件,您会看到不同的文件。

相关内容

最新更新