开发者

How to create tests for poco objects

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


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


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


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


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.


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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜