views:

331

answers:

9
+1  A: 

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.

eglasius
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
+1  A: 

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

shahkalpesh
+1  A: 

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.

Gerrie Schenck
@mandel clearly states that his properties have logic, thus tests must back up that logic.
Peter Lillevold
+3  A: 

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.

chrissie1
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.
mandel
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.
chrissie1
@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.
mandel
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.
chrissie1
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.
mandel
"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.
Esko Luontola
+1  A: 

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. http://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.

mezoid
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
+3  A: 

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

Arjan Einbu
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
@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.)
Arjan Einbu
+6  A: 

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);
}
Arjan Einbu
+1  A: 

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.

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

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.

Bealer