代码之家  ›  专栏  ›  技术社区  ›  Burt

规格模式单元测试[关闭]

  •  2
  • Burt  · 技术社区  · 14 年前

    我们最近采用了用于验证域对象的规范模式,现在希望引入域对象的单元测试来提高代码质量。

    我发现的一个问题是如何最好地对下面的示例中显示的验证功能进行单元测试。规范击中了数据库,所以我想能够模仿它,但由于它是在线实例化的,所以我不能这样做。我可以设计接口,但这会增加代码的复杂性,因为我们可能有很多规范,所以最终会有很多接口(记住,我们正在引入单元测试,不想给任何人一个借口来击落它)。

    在这种情况下,我们如何最好地解决在域对象中单元测试规范模式的问题?

    ...
    public void Validate()
    {
        if(DuplicateUsername())
        { throw new ValidationException(); }
    }
    
    public bool DuplicateUsername()
    {
        var spec = new DuplicateUsernameSpecification();
        return spec.IsSatisfiedBy(this);
    }
    
    4 回复  |  直到 14 年前
        1
  •  5
  •   Mark Seemann    14 年前

    更温和的介绍 接缝 可以通过制定核心方法来实现应用 virtual . 这意味着您可以使用 提取和覆盖 单元测试技术。

    在greenfield开发中,我发现这种技术不太理想,因为有更好的替代方案可用,但这是一种改进现有代码的可测试性的好方法。

    作为一个例子,您编写的规范会命中数据库。在这个实现中,您可以将规范的这一部分提取到 Factory Method 然后您可以在单元测试中覆盖它。

    一般来说,这本书 Working Effectively with Legacy Code 为如何使代码可测试提供了非常有价值的指导。

        2
  •  2
  •   DW.    14 年前

    如果你不想做一个工厂的构造注入,并使规格模拟…你考虑过打字吗?它对于处理这类事情是非常强大的。您可以告诉它模拟将要创建的X类型的下一个对象,它可以模拟任何东西,不需要虚拟机等。

        3
  •  1
  •   Carl Manaster    14 年前

    你可以提取 getDuplicateUsernameSpecification() 到它自己的公共方法中,然后为您的测试子类化并重写它。

        4
  •  1
  •   dh.    14 年前

    如果使用IOC,则可以解析重复的sername规范,并在测试中模拟最后一个规范。

    编辑:其思想是用工厂方法替换直接的构造函数调用。像这样:

    public bool DuplicateUsername()
    {
        var spec = MyIocContainer.Resolve<DuplicateUsernameSpecification>();
        return spec.IsSatisfiedBy(this);
    }