3

I am working on a lib that I want to release in open source. I have started writing the tests for the code, and I was wondering how I am suppose to test a property in a .Net object. Lets say I have the following:


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 _surname;
        }
        set{
            _surname = value;
        }
    }
}

I have two questions related to the code:

  1. How do I Unit test a Property that just has a getter (Like Name in the example)
  2. How do I Unit test a Property with a setter and a getter (Like Surname in the example)

I want to test properties that are that simple because I have already found errors in other code were Itellinsense did the wrong autocomplete and the property was not returning the correct variable.

Update:

I am not talking about simple properties as the one in the example, they do have some logic behind them and are quite hard to debug. Writing a test that uses the setter to test the getter and vice versa is not good because if there is a fail I won't know which method to blame. I am using properties because they were added as public variables and later more logic had to be added.

2
  • 2
    Provide an example that is closer to what you are really working with. Makes answering a lot easier. Commented Feb 27, 2009 at 9:44
  • 1
    > "they do have some logic behind them and are quite hard to debug." sounds like some refactoring might be required, and then you can unit-test the specific elements of the logic. Commented Feb 27, 2009 at 18:10

9 Answers 9

10

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.

Sign up to request clarification or add additional context in comments.

2 Comments

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.
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.
8

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

Comments

5

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...

3 Comments

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?
@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.)
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.
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.

6 Comments

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.
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.
@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.
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.
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.
|
1

Those property should be there because you have usages that needs them. As for these there should be unit tests, you should already have coverage for them. If there is no scenario that needs them, they possibly shouldn't be there at all.

1 Comment

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.
1

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

Comments

1

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.

1 Comment

@mandel clearly states that his properties have logic, thus tests must back up that logic.
1

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. https://stackoverflow.com/users/59332/mandel

Ok...since you insist on knowing how to do it....

[Test]
TestMethod()
{

    Person p = new Person();
    p.Name = "a name";
    p.Surname = "a surname";

    Assert.That(p.Name, Is.EqualTo("a name"));
    Assert.That(p.Surname, Is.EqualTo("a surname"));
}

However, that only works if you have setters....

If you only have getters there are only two ways I can think of that you can do this.

  1. know the return value in advance and assert against that.
  2. Use Reflection to set the value and then assert against that known value.

A better bit of advice would be to give up and test something worthwhile that actually adds value to your software. Testing getters and setters is an absolute waste of time unless there is something complex going on behind them....which is rarely the case.

1 Comment

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...
1

I think you meant that your getter-only propoerty uses private fields or other private data. If you need to set them, only way is to get them by Reflection (see all (something)Info classes in System.Reflection). But there is a hard discussion if this is a good practice.

2 Comments

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.
True, but I think he wants to test this single element so that input for those private fields will not interfere.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.