Click here to Skip to main content
15,884,298 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
[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);
     }
 }


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.
Posted
Updated 8-Nov-18 2:06am
Comments
Richard MacCutchan 8-Nov-18 4:33am    
You cannot assign 'void' to anything, as it has no meaning. You need to show the code that gives the error.
F-ES Sitecore 8-Nov-18 5:52am    
You can see the code from his other thread where I've already told him his code is not unit testable.

https://www.codeproject.com/Questions/1265657/How-do-I-unit-test-my-code
Richard MacCutchan 8-Nov-18 5:58am    
Yes, it's difficult to keep track of all the repeated questions.
Vacate 9-Nov-18 2:46am    
Thanks so much, you guys really helped me out and were able to put it simply enough for me to completely understand. Cheers

1 solution

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;
    }
}


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;
}


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);
    }
}


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.
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900