【问题标题】:JUnit test for reading csv file用于读取 csv 文件的 JUnit 测试
【发布时间】:2023-03-30 15:43:01
【问题描述】:

我有一种方法可以逐行读取 csv 文件并将每条记录放入列表中。我想测试这个方法。我所做的是创建了一个预期记录列表,然后创建了一个 csv 文件,其中包含我在列表中创建的相同记录。我阅读了这个新创建的 csv 文件并将其放入实际记录列表中。然后我比较了两个列表,但它给了我一个断言错误。

java.lang.AssertionError: 预期: 但是

这是我的代码

String[] record = new String[] { "source", "name", "component", "10", "100", "10.5", "200", "15.5" }; 

MyReader reader = new MyReader();

@Test
public void readDataTest () throws FileNotFoundException
{
    List< String[] > expectedrecords = new ArrayList< String[] >();
    expectedrecords.add( record );

    List< String[] > actualrecords = new ArrayList< String[] >();
    generatetestCSV( dirPath + "\\Messages_Statistics.csv" );
    actualrecords = reader.readData( dirPath + "\\Messages_Statistics.csv" );

    Assert.assertEquals( expectedrecords, actualrecords );
}

private void generatetestCSV ( String fileName )
{
    try
    {
        FileWriter writer = new FileWriter( fileName );
        writer.append( "source" );
        writer.append( ',' );
        writer.append( "name" );
        writer.append( ',' );
        writer.append( "component" );
        writer.append( ',' );
        writer.append( "10" );
        writer.append( ',' );
        writer.append( "100" );
        writer.append( ',' );
        writer.append( "10.5" );
        writer.append( ',' );
        writer.append( "200" );
        writer.append( ',' );
        writer.append( "15.5" );
        writer.append( '\n' );
        writer.flush();
        writer.close();
    }
    catch ( IOException e )
    {
        e.printStackTrace();
    }
}

MyReader 类中的 readData 是

  public List< String[] > readData ( String csvFile ) throws FileNotFoundException
{

    List< String[] > records = new ArrayList< String[] >();
    BufferedReader br = new BufferedReader( new FileReader( csvFile ) );
    String line = "";
    try
    {
        if ( csvFile != null )
        {
            if ( csvFile.contains( "Messages_Statistics" ) )
            {
                while ( ( line = br.readLine() ) != null )
                {
                    String[] record = line.split( "," );
                    if ( records.size() < LIMIT )
                        records.add( record );
                    else
                        break;
                }
            }

        }
    }
    catch ( FileNotFoundException e )
    {
        //logger.error( "Error in reading CSV file", e );
    }
    catch ( IOException e )
    {
        e.printStackTrace();
    }
    finally
    {
        if ( br != null )
        {
            try
            {
                br.close();
            }
            catch ( IOException e )
            {
                e.printStackTrace();
            }
        }
    }
    return records;
}

【问题讨论】:

  • 你不能用Assert.assertEquals来比较List&lt;String[]&gt;
  • 那我应该用什么?

标签: java file junit junit4


【解决方案1】:

您不能使用Assert.assertEquals 来比较List&lt;String[]&gt;。这不起作用:

List<String[]> expected = new ArrayList<>();
expected.add(new String[]{"foo", "bar"});
expected.add(new String[]{"baz", "qux"});

List<String[]> actual = new ArrayList<>();
actual.add(new String[]{"foo", "bar"});
actual.add(new String[]{"baz", "qux"});

Assert.assertEquals(expected, actual); // Fails!

你必须这样做:

List<String[]> expected = new ArrayList<>();
expected.add(new String[]{"foo", "bar"});
expected.add(new String[]{"baz", "qux"});

List<String[]> actual = new ArrayList<>();
actual.add(new String[]{"foo", "bar"});
actual.add(new String[]{"baz", "qux"});

assertEquals(expected.size(), actual.size());
for (int i = 0; i < expected.size(); i++) {
    for (int j = 0; j < expected.get(i).length; j++) {
        Assert.assertEquals(expected.get(i)[j], actual.get(i)[j]);
    }
}

【讨论】:

  • 你能解释一下你的for循环吗
  • 外部循环围绕List(CSV 的行),内部循环围绕String[](行的单元格)。 expected 中的每个单元格都会与 actual 中的相应单元格进行比较。
  • 为什么不使用assertArrayEquals - 如此处所述stackoverflow.com/questions/3457941/… - 与toArray结合使用。
【解决方案2】:

编写一个将列表格式化为字符串的函数,然后比较字符串。如果他们匹配,你很好。如果不这样做,则字符串 diff 比谈论列表中的索引的异常更具可读性。特别是如果您在 IntelliJ 或 Eclipse 中运行测试,它们会在其中格式化字符串以使差异非常明显。

【讨论】:

    【解决方案3】:
    Assert.assertEquals( expectedrecords, actualrecords );
    

    这是比较不同的列表对象实例。您需要遍历一个循环并断言列表的各个条目

    如下更改您的断言检查

     Assert.assertEquals(expectedrecords.size(),actualrecords.size());
        int count = 0;
    
        for(String[] lineData: expectedrecords)
        {
            String[] actualRecordData = actualrecords.get(count);
            count++;
    
            Assert.assertEquals( lineData.length,actualRecordData.length);
    
            for(int i = 0; i < lineData.length; i++)
            {
                Assert.assertEquals( lineData[i],actualRecordData[i]);
            }
        }
    

    【讨论】:

      猜你喜欢
      • 2014-10-06
      • 2021-05-28
      • 1970-01-01
      • 1970-01-01
      • 2020-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多