2

I am trying to write a unit test for method with void. But, I could not find any examples or clear answers. Following is a method I used in my programme and I want to write a unit test for this. Can anyone help me in this regard. Thanks in advance.

    //method for disable all comboBoxes
    private void comboDisable() 
    {
        foreach (var j in this.Controls)
        {
            if (j.GetType().Equals(typeof(ComboBox)))
            {
                ComboBox cmb = j as ComboBox;
                cmb.Enabled = false;
            }
        }
    }
Chandan Kumar
  • 4,570
  • 4
  • 42
  • 62
Buddhi
  • 79
  • 2
  • 8
  • Where are you stuck? – Ofir Winegarten Apr 22 '17 at 04:51
  • Coding Tip: simplify `if (j.GetType().Equals(typeof(ComboBox)))` to `if (j is ComboBox)`. Go one step further and you can eliminate that & just write `var cmb = j as ComboBox; if (cmb != null) { cmb.Enabled = false; }` – Anthony Pegram Apr 22 '17 at 04:52
  • This code is working. I am trying to write a unit test case for this method and I am not sure how to approach and what to write?. – Buddhi Apr 22 '17 at 04:55
  • 2
    As for unit testing void methods -- typically, such methods will *do* something. A unit test would verify that the *something* was done. Assert on the effect. (If you can't do that with the code that's written, refactor until you can.) – Anthony Pegram Apr 22 '17 at 04:55
  • Unit Tests check specific functionality, which change state of your objects. So, after this functionality having been executed you compare expected state of objects with actual state of objects. As a result, u need to rewrite your method to get Combobox collection as a parameter. Then just check after method's call. Anyway, u need access to your target objects. Suspect u did not found answer cause of private method considered as implementation details, and they are not tested. – Ryan Apr 22 '17 at 04:56
  • By the way, this is a private method, are you sure you need to test it? usually private method are an implementation detail, and the public behavior is the one that is needed to be tested, and by this test the private method will be covered as well. These private methods are often the result of a refactoring of a tested public method. – Ofir Winegarten Apr 22 '17 at 05:00
  • First off you dont typically test private methods. Second separate your business logic from the presentation tier and using binding controls you don't need to unit test the GUI. Third to test a method like this you need to use Mocking & Dependency Injection. – Jeremy Thompson Apr 22 '17 at 05:02
  • If this is a public method, would I be able to write a unit test? If so can you help me with an example. – Buddhi Apr 22 '17 at 05:04

2 Answers2

1

As already mentioned, unit tests usually target application logic public methods, not UI related methods.

If you really insist on testing your method, you should follow these steps:

1) Setup phase - this a phase to initialize the context of your tests. In you case initializing and opening of the form containing the combo boxes

2) Tear down phase - this is a phase to leave the things as if your tests never ran. E.g. close and dispose in your form

3) Actual test - get some combo boxes instances, have them enabled, call your method, check that all checkboxes are disabled

Some (pseudo-)-code using NUnit framework attributes (not tested, it is just to get you started):

[TestFixture]
public class YourFormTests
{
    private Form frm;

    [OneTimeSetUp]
    public void SetUp()
    {
        frm = new Form();
        frm.Show();
    }

    [OneTimeSetup]
    public void TearDown()
    {
        frm?.Close();
        frm?.Dispose();
    }

    [Test]
    public void TestComboDisabled()
    {
        frm.cmbSomeName.Enabled = true;
        frm.comboDisable();
        Assert.IsFalse(frm.cmbSomeName.Enabled, "Combo is not disabled");
    } 
}

This assumes your method is public and also tested combo box. Theoretically, you can dynamically invoke a private method, but this is really ugly and not recommended (method rename produced a TargetInvocationException instead of compilation error).

This should provide a basic idea on the unit testing creation, but you should really read the basics.

Community
  • 1
  • 1
Alexei - check Codidact
  • 22,016
  • 16
  • 145
  • 164
0

As some have mentioned, you really should separate your business logic from your UI. The issue I see here, is what would you be unit testing? Are you trying to see if a certain combo box was disabled? If ALL comboboxes were disabled?

What I would suggest is very... questionable. However, if you want to unit test the logic with your UI... Perhaps create an empty collection of comboboxes, add every combobox that was disabled to that collection, and then have the method return the collection of disabled comboboxes. Then perhaps assert that they are all disabled.

Toskr
  • 379
  • 2
  • 7