Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it wrong to extend class in order to unit test it's protected property?

Tags:

unit-testing

I had to make a fix, where the line of code was removed for the second time. So I decided to write a unit test just for that.

A Class in its constructor sets a property that I want to test. This property happens to be protected so I can't access it in the unit test.

 [Test]
 public void Constructor_WhenCalled_ThenSomePropertyIsPopulated()
 {
     var vm= new SomeViewModel();
     //line below doesn't compile as SomeProperty is protected
     Assert.IsNotNull(vm.SomeProperty);

So I decided, in my unit test file, to extend that class (it wasn't sealed) and expose the protected property as a public getter:

public class SomeViewModelExtended : SomeViewModel
{
    public SomeViewModelExtended() : base() { }

    public new object SomeProperty
    {
        get { return base.SomeProperty; }
    }
}

 //now I can test
 [Test]
 public void Constructor_WhenCalled_ThenSomePropertyIsPopulated()
 {
     var vm= new SomeViewModelExtended();
     Assert.IsNotNull(vm.SomeProperty);

Now there's an argument on my team that I should only be testing public interfaces among other things and that this is a total quick and dirty hack.

But isn't one of the purposes of unit tests to preserve the code base from unwanted changes? If this is totally wrong what else should do?

like image 461
denis morozov Avatar asked Dec 14 '25 05:12

denis morozov


1 Answers

A protected variable is part of the interface. It's part of the interface that any sub class can use. This question has a good summary on protected variables. Is it good practice to make member variables protected?

If you allow derived classes access to their base class' data, then derived classes need to take care to not to invalidate the base class' data's invariants. That throws encapsulation out of the window and is just wrong. (So do getters and setters, BTW.)

In answer to your question, if the variable should not be accessed by sub classes then it should be private. Otherwise your unit test is valid and arguably it should have been implemented earlier!

like image 52
Steve Avatar answered Dec 15 '25 19:12

Steve