单元测试我的项目 [英] Unit testing my project

查看:61
本文介绍了单元测试我的项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

[TestClass()]
 public class UnitTest
 {
     [TestMethod()]
     public void BindDataCSV_FilePathIsEmpty()
     {
         // Arrange
         var sut = new Woodstocks();
         // Act
         var result = sut.BindDataCSV(string.Empty);
         //Assert
         Assert.Equals(0, result.Rows.length);
     }
 }





我尝试了什么:



大家好,我正在尝试对我的BindDataCSV函数进行单元测试,看它是否会返回null或空DataTable。我得到的错误是无法为隐式类型的变量分配void。

我明白这是一个非常新手的问题,但任何帮助都会受到赞赏。



What I have tried:

Hi guys, I am trying to unit test my BindDataCSV function to see if it will return a null or empty DataTable. The error i am getting is cannot assign void to an implicitly-typed variable.
I understand this is a very novice question but any help would be appreciated.

推荐答案

为了回答您的直接问题,BindDataCSV什么都不返回(它的返回类型为void),因此您无法将其返回值分配给变量,因为没有任何内容可以返回。



要回到我对你的其他线程的评论,这段代码是不可测试的。您需要将可测试的位提取到它们自己的class \functions中。所以我会做一些事情,比如将BindDataCSV更改为;



To answer your immediate question, BindDataCSV returns nothing (it has "void" as its return type) so you can't assign its return value to a variable as there is nothing to return.

To get back to my comments on your other thread, this code is not testable as it is. You need to extract the bits that are testable to their own class\functions. So I'd do something like change the BindDataCSV to;

private void BindDataCSV(string filePath)
{ 
    string[] lines = System.IO.File.ReadAllLines(filePath);

    DataTable dt = GetDataTable(lines);

    if (dt.Rows.Count > 0)
    {
        dataGridView1.DataSource = dt;
    }
}





您的单元测试不应该访问任何外部资源,如文件系统,理想情况下他们不应该访问GUI元素,因为单元测试需要在任何上下文中自动运行而没有任何依赖性。因此,更新的函数将重要的逻辑提取到一个新函数(GetDataTable)中,并执行所有无法进行单元测试的事情,如访问文件,更新数据网格等。



GetDataTable函数如下所示;





Your unit tests shouldn't access any external resources like the file system, and ideally they shouldn't access GUI elements either as unit tests need to run automatically in any context without any dependencies. So the updated function extracts the important logic into a new function (GetDataTable) and does all the things you can't unit test like access files, update the data grid etc.

The GetDataTable function looks like this;

public DataTable GetDataTable(string[] lines)
{
    DataTable dt = new DataTable();

    if (lines.Length > 0)
    {
        //first line to create header

        string firstline = lines[0];
        //reads first line of string array at index 0

        string[] headerLabels = firstline.Split(',');
        //splits the firstline using comma delimited string

        foreach (string headerWord in headerLabels)
        {
            dt.Columns.Add(new DataColumn(headerWord));
            //added DataColumns for header
        }

        //for data


        for (int r = 1; r < lines.Length; r++)
        {
            string[] dataWords = lines[r].Split(',');
            //split strings into lines
            DataRow dr = dt.NewRow();
            //inset a new row into a data table
            int columnIndex = 0;
            //start of column is 0 index
            foreach (string headerWord in headerLabels)
            {
                dr[headerWord] = dataWords[columnIndex++];
                //increment the value by 1 in columnIndex

            }
            dt.Rows.Add(dr);
            //adds DataRow in the DataTable
        }
    }

    return dt;
}





此函数作用于字符串数组,不访问GUI或其他任何内容,因此这是现在可以测试了。我在下面写了几个单元测试,但是你可以自己决定要测试的所有内容。





This function acts on an array of strings and doesn't access the GUI or anything else, so this is now testable. I've written a few unit tests below, but it's up to you to decide everything you want to test.

[TestClass]
public class UnitTest1
{
    [TestMethod]
    public void GetDataTable_ColumnsAreLoaded()
    {
        // Arrange
        Form1 form1 = new Form1();

        string[] lines = new string[] { "Col A, Col B", "Row 1 A, Row 1 B" };

        // Act
        DataTable dt = form1.GetDataTable(lines);

        // Assert
        Assert.AreEqual(2, dt.Columns.Count);
    }

    [TestMethod]
    public void GetDataTable_ColumnsAreCorrect()
    {
        // Arrange
        Form1 form1 = new Form1();

        string[] lines = new string[] { "Col A, Col B", "Row 1 A, Row 1 B" };

        // Act
        DataTable dt = form1.GetDataTable(lines);

        // Assert
        Assert.AreEqual("Col A", dt.Columns[0].Caption);
        Assert.AreEqual("Col B", dt.Columns[1].Caption);
    }

    [TestMethod]
    public void GetDataTable_RowsAreLoaded()
    {
        // Arrange
        Form1 form1 = new Form1();

        string[] lines = new string[] { "Col A, Col B", "Row 1 A, Row 1 B" };

        // Act
        DataTable dt = form1.GetDataTable(lines);

        // Assert
        Assert.AreEqual(1, dt.Rows.Count);
    }
}





如果你运行这些测试,你会看到GetDataTable_ColumnsAreCorrect实际上失败了,它会告诉你原因。它期待Col B,但得到了Col B。注意列之前的额外空格,这是因为你没有修改GetDataTable中的列名,所以这是你的单元测试已经发现的错误。



所以这就是单元测试的内容,它不是一种自动化整个过程的方式,而是提取重要逻辑并测试该逻辑;我在测试中根本没有触及BindDataCSV,而是在测试逻辑。另外,正如您从上面可以看到的那样,除非您已经考虑过单元测试,否则您的所有代码都不会是单元可测试的。



If you run these tests you'll see that GetDataTable_ColumnsAreCorrect actually fails, and it will tell you why. It was expecting "Col B" but got " Col B". Note the extra space before the column, and this is because you are not trimming the column names in GetDataTable, so that's a bug your unit tests have found already.

So that's what unit testing is about, it isn't a way of automating your whole process, it is about extracting the important logic and testing just that logic; I'm not touching BindDataCSV at all in my tests, instead I'm testing the logic. Also as you can see from above not all your code is going to be unit testable unless you have written it with unit tests in mind.


这篇关于单元测试我的项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆