简体   繁体   English

单元测试装饰器模式

[英]Unit testing the decorator pattern

I recently solved one of my problems using the decorator pattern. 我最近使用装饰器模式解决了我的问题之一。 Everything works fine and everything is decoupled enough (or so I think) that I am able to unit test each validitable field separately. 一切正常,一切都解耦了(或者我认为),我能够分别对每个可验证字段进行单元测试。

My question is, if the NameValidator and AgeValidator both pass the tests for the Validate() and IsValid() (abstract) functions. 我的问题是,如果NameValidator和AgeValidator都通过了Validate()和IsValid()(抽象)函数的测试。 Do I still need to unit test my ValidationDecorator class (not created yet)? 我还需要对ValidationDecorator类(尚未创建)进行单元测试吗? ValidationDecorator would be reponsible for decorating my validator with each validation class. ValidationDecorator将负责为每个验证类装饰我的验证器。

public abstract class FieldValidator
{
    protected IMessage validateReturnType;

    public FieldValidator() { }

    public bool IsValid()
    {
        return (validateReturnType.GetType() == typeof(Success));
    }
}

public class NameValidator : FieldValidator, IValidator
{
    private string name;

    public NameValidator(string _name) { 
        name = _name;
    }

    public IMessage Validate()
    {
        if (name.Length < 5)
        {
            validateReturnType = new Error("Name error.");
        }
        else
        {
            validateReturnType = new Success("Name no errror.");
        }

        return validateReturnType;
    }
}

public class AgeValidator : FieldValidator, IValidator
{
    private int age;

    public AgeValidator(int _age)
    {
        age = _age;
    }

    public IMessage Validate()
    {
        if (age <= 18)
        {
            validateReturnType = new Error("Age error.");
        }
        else
        {
            validateReturnType = new Success("Age no errror.");
        }

        return validateReturnType;
    }
}

public interface IValidator
{
    IMessage Validate();
    bool IsValid();
}

This is my unit test. 这是我的单元测试。

[TestFixture]
public class ValidatorTest
{
    Type successType;
    Type errorType;

    Model m;

    [SetUp]
    public void SetUp()
    {
        successType = typeof(Success);
        errorType = typeof(Error);

        m = new Model();
        m.Name = "Mike Cameron";
        m.Age = 19;
        m.Height = 325;

        Validator v = new Validator();
        v.Validate(m);
    }

    [Test]
    public void ValidateNameTest()
    {
        IValidator im = new NameValidator(m.Name);

        IMessage returnObj = im.Validate();

        Assert.AreEqual(successType, returnObj.GetType());
    }

    [Test]
    public void IsValidNameTest()
    {
        IValidator im = new NameValidator(m.Name);

        IMessage returnObj = im.Validate();

        Assert.IsTrue(im.IsValid());
    }

    [Test]
    public void ValidateAgeTest()
    {
        IValidator im = new AgeValidator(m.Age);

        IMessage returnObj = im.Validate();

        Assert.AreEqual(successType, returnObj.GetType(), "Must be over 18");
    }

    [Test]
    public void IsValidAgeTest()
    {
        IValidator im = new AgeValidator(m.Age);

        IMessage returnObj = im.Validate();

        Assert.IsTrue(im.IsValid());
    }

Thank you. 谢谢。

The rule of thumb is "test everything which could possibly break". 经验法则是“测试所有可能破坏的东西”。 Now, judging what can possibly break is far from trivial under real life circumstances. 现在,在现实生活中判断可能会破裂的东西并不容易。 It takes practice and experience to get it right. 正确实践需要实践和经验。 And it is impossible to give general advice, especially without seeing your design and code. 而且不可能给出一般性建议,尤其是在没有看到您的设计和代码的情况下。

So in the end, only you can reliably assess whether or not you feel confident enough that ValidationDecorator is so trivial, it can never break. 因此,最后,只有您可以可靠地评估您是否对ValidationDecorator如此微不足道,永远不会失败感到足够有信心。 If in doubt, it is better to err on the side of too many tests :-) That means you spend some extra time on a possibly unimportant task. 如有疑问,最好在过多的测试中出错:-)这意味着您在可能不重要的任务上花费了更多时间。 The opposite - failing to write a needed unit test - means you may let a bug slip through your net, which is typically a bigger issue. 相反-未能编写所需的单元测试-意味着您可能会让漏洞漏出网络,这通常是一个更大的问题。

Yes, you should unit test any class that could contain bugs. 是的,您应该对可能包含错误的任何类进行单元测试。 To unit test your ValidationDecorator class, you should use mock or stub implementations of IValidator. 要对ValidationDecorator类进行单元测试,应使用IValidator的模拟或存根实现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM