UnitTesting Properties in .Net?

37

Solution 1

How do I Unit test a Property that just has a getter (Like Name in the example)

Really not so different from testing if you had a setter. you'll just need to find another way of determining the output. Could be in a ctor, or the result of other setters/operations on the object.

[Test]
public void NamePropTest()
{
    Person p = new Person();

    //Some code here that will set up the Person object
    //  so that you know what the name will be

    Assert.AreEqual("some known value...", p.Name);
}

If we had setters for Name and SurName, but only a getter for FullName, the test could look like this:

[Test]
public void NamePropTest()
{
    Person p = new Person();

    p.Name = "Sean";
    p.Surname = "Penn";

    Assert.AreEqual("Sean Penn", p.FullName);
}

Solution 2

Don's waste your time on writing silly tests for getters and setters.

Another test will probably set the Name and then get that property so you will have code coverage for the getter.

You should test anything public facing, including properties. If you don't test a property, you run the risk that someone may add some logic inside it, breaking the functionality.

Also you shouldn't rely on it being tested in other tests. This makes your tests brittle, and makes it harder to identify where the problem is as a test will be testing more than one thing.

Solution 3

You should test properties. Also automatic properties!

Unittests are about assuring that changes to the program, don't break the program.

You could end up changing a property implementation at some time, and you want to make sure the program still works as expected. You do that with your tests.

Even if you use automatic properties (as a replacement for fields/member variables), the reason for making them properties is in case you want to change their implementation later on. Then you'll want the tests to be there.

EDIT: (In response to shahkalpesh's comment...)

If you are changing the implementation, the tests might also require the change. So, I don't know of why someone should test simple get/set?

Starting with this class:

public class TimeOfDay
{
    public int Hour{get; private set;}
    public int Minute{get; private set;}

    public TimeOfDay(int hour, int minute)
    {
        Hour = hour;
        Minute = minute;
    }
}

When changing the implementation, the tests are still valid!

public class TimeOfDay
{
    public int _minutesSinceMidnight = 0;

    public int Hour
    {
        get { return _minutesSinceMidnight / 60; }
        set { _minutesSinceMidnight = value * 60 + Minutes; }
    }

    public int Minute
    {
        get { return _minutesSinceMidnight % 60; }
        set { _minutesSinceMidnight = Hour * 60 + value; }
    }

    public TimeOfDay(int hour, int minute)
    {
        Hour = hour;
        Minute = minute;
    }
}

Throw in some date and time arithmetic functions or something, and I would like the tests to show that everything still works...

Solution 4

I think you should test, them if you write them like you did. Afterall you can mistype something.

Just something like

var person = New Person();
person.Surname = "test";
Assert.AreEqual("test", person.Surname);

After all TDD and unit testing n general is all about avoiding the most bugs you can.

If by accident you had written this.

public class Person{
    #region variables
    private string _name = String.Empty;
    private string _surname = String.Empty;
    #region properties
    public string Name{
        get{
             return _name;
        }
    }
    public string Surname{
        get{
            return _name;
        }
        set{
            _name = value;
        }
    }
}

then you would have a bug.

Testing the automatic properties is perhaps less valuable. But that's another question.

Solution 5

As I understand, you shouldn't be testing properties (i.e. those which are simple get/set).

I am not sure what version of c# you are using. But, you can use automatic properties to avoid the simple set/get problems that you are facing.

See this link

Share:
37
Kirguduck
Author by

Kirguduck

Updated on June 28, 2022

Comments

  • Kirguduck
    Kirguduck almost 2 years

    I need to make a spinner like on picture below. My question is - how to add arrow(dropdown hint) to right part for first element in spinner. Better if it(I mean arrow but not "Select test") will disappear after user press it

    enter image description here

  • mandel
    mandel about 15 years
    My question is more related of HOW to write the test. I have been thinking about it and I need to access the private values to make sure that the properties work as expected, otherwise I do not know how to do it.
  • mandel
    mandel about 15 years
    yes, but in this case your test makes the getter and setter to be related which means that at some point you are assuming that the getter or setter works for sure. It also assumes that you have a getter in the Name which is not the case... the properties are simple because they are examples...
  • mandel
    mandel about 15 years
    so, if the test fails, how is it to bale, the getter or the setter?? The properties in the example are simple, but the real world ones are not and they are hard to debug.
  • chrissie1
    chrissie1 about 15 years
    Then ask the question you want to ask and don't try to oversimplify. People will only answer the question not what you think is the question.
  • mandel
    mandel about 15 years
    @chrissie I don't think writing 200 lines of code is a good idea, If I where using simple properties I would not even write them and would let the compiler do the work for me.
  • chrissie1
    chrissie1 about 15 years
    So than you should surely be testing them. But if you have 200 lines of code in a setter than you have a SRP problem. We can't give you suggestions if we have to guess the problem.
  • mandel
    mandel about 15 years
    I though single responsibility principle (SRP) is focused on classes rather that method or properties. In this case the object is taking care of his data, the only problem is that there it does it in a lazy manner and has to check a db.
  • shahkalpesh
    shahkalpesh about 15 years
    If you are changing the implementation, the tests might also require the change. So, I don't know of why someone should test simple get/set?
  • Esko Luontola
    Esko Luontola about 15 years
    "After all TDD and unit testing in general is all about avoiding the most bugs you can." -- TDD is all about design. Low bug rates are a happy side effect.
  • Arjan Einbu
    Arjan Einbu about 15 years
    @shahkalpesh: I would still write a test. Changing requirements will often lead to changing the tests (not only for properties). I can't NOT write a test, because it MIGHT need to be changed sometime in the future. (I've also added an example of why in my answer.)
  • Peter Lillevold
    Peter Lillevold about 15 years
    @mandel clearly states that his properties have logic, thus tests must back up that logic.
  • Arjan Einbu
    Arjan Einbu about 15 years
    I'd be suprised if he creates variables that ONLY reflection can get to. These variable will have a value, and probably also a way they set that value (if it is something else than the default values), even if it isn't as straightforward as setting a property.
  • Scott Marcus
    Scott Marcus over 8 years
    You certainly "can" write tests for all public members, but if you are interested in the cost/benefit aspect of unit testing, then no, do not write unit tests on everything that is public. Really, you don't want to write a test on something as simple as a property that contains no logic (a simple getter/setter). What benefit do you get from that test? If your argument is that someone may come along later and add logic, then that's the point when a test should be added.
  • Casey ScriptFu Pharr
    Casey ScriptFu Pharr over 8 years
    One good time on unit testing a setter, and I have done this, is when the setter is altering the data such as checking length of string, masking all except last 4 characters. Things like that, where there is expected logic in the getter. I think that is fine to unit test.
  • Sudhanshu Mishra
    Sudhanshu Mishra about 7 years
    May I raise an alternate point of view? If there is complex logic to be written, especially if it can potentially throw an exception, semantically, one is better of writing those as methods rather than properties. Then, it is also an easier discussion on whether that method has coverage or not.