UnitTesting Properties in .Net?
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
Kirguduck
Updated on June 28, 2022Comments
-
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
-
mandel about 15 yearsMy 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 about 15 yearsyes, 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 about 15 yearsso, 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 about 15 yearsThen 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 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 about 15 yearsSo 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 about 15 yearsI 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 about 15 yearsIf 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 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 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 about 15 years@mandel clearly states that his properties have logic, thus tests must back up that logic.
-
Arjan Einbu about 15 yearsI'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 over 8 yearsYou 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 over 8 yearsOne 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 about 7 yearsMay 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.