views:

74

answers:

5

Hi,

I'm new to mocking/testing and wanting to know what level should you go to when testing. For example in my code I have the following object:

public class RuleViolation
{
    public string ErrorMessage { get; private set; }
    public string PropertyName { get; private set; }

    public RuleViolation( string errorMessage )
    {
        ErrorMessage = errorMessage;
    }

    public RuleViolation( string errorMessage, string propertyName )
    {
        ErrorMessage = errorMessage;
        PropertyName = propertyName;
    }
}

This is a relatively simple object. So my question is:

Does it need a unit test?

If it does what do I test and how?

Thanks

+4  A: 

it doesn't contain any logic => nothing to test

Andrey
+1 Thanks for this simple rule of testing.
Will Marcouiller
+3  A: 

I would say probably not. The only thing that you would probably want to verify if it is extremely important are the access modifiers:

public string ErrorMessage { get; private set; }
public string PropertyName { get; private set; }

If it is really really important that code outside the class cannot modify them that might be the only thing I would try and verify.

Here is how you can get the accessors in a property:

class Program
    {
        static void Main(string[] args)
        {
            var property = typeof(Test).GetProperty("Accessor");

            var methods = property.GetAccessors();
        }
    }



    public class Test
    {
        public string Accessor
        {

            get;
            private set;
        }    

    }

With the property.GetAccessors();

You can see if the setter is there. If it is, then the setter is public. (There is also properties IsPrivate and IsPublic you can use to verify the other Accessors as well).

Kevin
+1 this is the kind of thing that is difficult to notice as the code evolves over time, and it's so simple to test for there is little reason not to test
Cocowalla
how would you actually test something like this? As you cant try to set a property as it shows a compiler error? Or am I missing something simple?
Simon G
+1 Very nice tiny test you have here! Lean and swift, just as we like'em! Thanks!
Will Marcouiller
A: 

Even if simple, there's logic in your constructors. I would test that:

RuleViolation ruleViolation = new RuleViolation("This is the error message");
Assert.AreEqual("This is the error message", ruleViolation.ErrorMessage);
Assert.IsEmpty(ruleViolation.PropertyName);

RuleViolation ruleViolation = new RuleViolation("This is the error message", "ThisIsMyProperty");
Assert.AreEqual("This is the error message", ruleViolation.ErrorMessage);
Assert.AreEqual("ThisIsMyProperty", ruleViolation.PropertyName);
Danny T.
+1  A: 

You could unit test this object, but it's so simple as to not require it. The test would be something like (NUnit example)

[Test]
public void TestRuleViolationConstructorWithErrorMessageParameterSetsErrorMessageProperty() {
    // Arrange
    var errorMessage = "An error message";

    // Act
    var ruleViolation = new RuleViolation(errorMessage);

    // Assert
    Assert.AreEqual(errorMessage, ruleViolation.ErrorMessage);
}

There's little value to writing tests like these, however, as you are testing that the .NET framework's properties work correctly. Generally you can trust Microsoft to have got this right :-)

Regarding mocking, this is useful when your class under test has a dependency, perhaps on another class in your own application, or on a type from a framework. Mocking frameworks allow you call methods and properties on the dependecy without going to the trouble of building the dependency concretely in code, and instead allow you to inject defined values for properties, return values for methods, etc. Moq is an excellent framework, and a test for a basic class with dependency would look something like this:

[Test]
public void TestCalculateReturnsBasicRateTaxForMiddleIncome() {
    // Arrange
    // TaxPolicy is a dependency that we need to manipulate.
    var policy = new Mock<TaxPolicy>();
    bar.Setup(x => x.BasicRate.Returns(0.22d));

    var taxCalculator = new TaxCalculator();

    // Act
    // Calculate takes a TaxPolicy and an annual income.  
    var result = taxCalculator.Calculate(policy.Object, 25000);

    // Assert
    // Basic Rate tax is 22%, which is 5500 of 25000.
    Assert.AreEqual(5500, result);
}  

TaxPolicy would be unit tested in its own fixture to verify that it behaves correctly. Here, we want to test that the TaxCalculator works correctly, and so we mock the TaxPolicy object to make our tests simpler; in so doing, we can specify the behaviour of just the bits of TaxPolicy in which we're interested. Without it, we would need to create hand-rolled mocks/stubs/fakes, or create real instances of TaxPolicy to pass around.

There's waaaaay more to Moq than this, however; check out the quick-start tutorial to see more of what it can do.

alastairs
A: 

If it were my code and my object I would have tests for it, no matter how simple or complicated the class is, period. Even if the class seems unlikely to break, tests are where, IMO, you document your assumptions, design decisions, and proper usage.

By doing so, you not only validate that what you have works as intended, but you have the opportunity to think through typical scenarios (what happens if the ctor params are null or empty or have white space at the end? Why is the PropertyName optional in an immutable class?).

And IF (when?) requirements change you have a solid starting point for addressing that. And IF this trivial class somehow doesn't interact nicely with all of the other classes, you may have a test to catch that before your customers do.

It's just the right way to engineer your code.

HTH,
Berryl

Berryl