0
votes

I'm relatively new to TDD, and still trying to learn to apply some of the concepts. Here's my situation.

I've got a WinForm with a DataGridView. I'm trying to write a test for the routine to be called by a button click that will perform some operations on the selected rows of the grid. So I will be passing in the DataGridViewSelectedRowCollection object (i.e, the dgv.SelectedRows property at the time the button is clicked).

The DataGridViewSelectedRowCollection object has no constructor, so the only way I can figure to create it is to put together a DataGridView in my test project, then select some rows and pass in the SelectedRows property. But clearly, I don't want to re-create the whole form there.

So I do a DataGridView dgv = new DataGridView(), and gin up a BindingList (actually a SortableBindingList) just like the grid is bound to in the real application. The test list has 3 rows in it. And I do a dgv.DataSource = myList.

Now, at that point in the real application, the grid view is bound. If I look at dgv.Rows.Count, it's equal to the number of rows in the list. However, in my test, setting the DataSource property to the list still results in zero rows in the grid.

I'm thinking there's something missing in the creation of the gridview that normally gets done when it's added to the control list of the form. It probably initializes the handler for the OnDataSourceChanged event or something, and that isn't being done in my test code, but I'm really at a loss as to how to fix it, again, without re-creating a whole form object in my test fixture.

Here's the relavant code form my test method:

        DataGridView residueGrid = new DataGridView();
        List<Employee> baseListToGrid = new List<Employee>();
        SortableBindingList<Employee> listToGrid = new SortableBindingList<Employee>(baseListToGrid);
        residueGrid.DataSource = listToGrid;
        for (int ix = 1; ix < 4; ix++)
        {
             listToGrid.Add(ObjectMother.GetEmployee(ix));
        }
        Assert.AreEqual(3, listToGrid.Count, "SortableBindingList does not have correct count");
        Assert.AreEqual(3, residueGrid.Rows.Count, "DataGrid is not bound to list");

Thanks for any help you can give me.

2
You want to assign the DataSource -after- populating it (or use a BindingSource)..stuartd
Thanks, Stuart, but I tried it after populating it as well, with the same results. (In fact, that was my first attempt, and then I looked at some of the examples which bound the datasource first, then populated it, so I tried it that way, and that was the code I ended up posting. Although the examples did use BindingSources.) I do see a lot of the posted examples using BindingSources. I was trying to avoid it for two reasons: 1) I don't understand them. It seems like it just adds another level of indirection/confusion to the mix. 2) The code that I'm testing doesn't use a Binding Source.Dave Hanna

2 Answers

0
votes
DataGridView residueGrid = new DataGridView();
List<Employee> baseListToGrid = new List<Employee>();
SortableBindingList<Employee> listToGrid = new SortableBindingList<Employee>(baseListToGrid);

// residueGrid.DataSource = listToGrid; <-- move this line...

for (int ix = 1; ix < 4; ix++)
{
     listToGrid.Add(ObjectMother.GetEmployee(ix));
}

// residueGrid.DataSource = listToGrid; <-- ...to here!

Assert.AreEqual(3, listToGrid.Count, "SortableBindingList does not have correct count");
Assert.AreEqual(3, residueGrid.Rows.Count, "DataGrid is not bound to list");

A useful structure for writing test is the following:

public void MyTest()
{
    // Arrange
    // Act
    // Assert
}

In this case, Arrange would be instantiating all the objects, and filling the list. Act is where you set the data source of the gridview, and Assert is where you check that everything went OK. I usually write out those three comment lines each time I start writing a test.

0
votes

Well, I solved the problem, and pretty much confirmed that it is something being done in the initialization of the control when added to the form that makes the DataSource binding work.

It suddenly dawned on me that that the "target" created by the MS testing framework is a private accessor to the Form itself. So I changed the line DataGridView residueGrid = new DataGridView(); in the above code to, instead of creating a new DGV object, just reference the one on the target form: DataGridView residueGrid = target.residueGrid;

That change made everything work as expected.