单元测试DTO和领域对象

3
我计划编写一个类似抽象类的东西,用于测试所有DTO和DOMAIN对象。这个类将接收可模板化对象(泛型),并使用反射获取其内部属性的类型,并为识别出来的基本类型分配一些默认值,稍后通过访问它们来断言这些类型的值。这样,每当我的DTO测试继承此类时,大部分代码都可以通过在测试中编写一行代码进行测试。这只是一个想法,我想知道你们是否认为我正在重新发明轮子,是否已经存在类似的东西?如果有更好的方法来测试DTO和域对象,可以用更少且可重复使用的代码来实现吗?

2
如果我理解正确的话,您尝试测试域对象和DTO之间的映射是否完整,即没有属性丢失。如果您在问题中添加编程语言,可能已经有解决方案了。从我的经验来看,在.dot中仅当您拥有许多dtos(> 20)时才值得付出努力。您的测试API必须考虑从转换中排除的属性以及可能不同的集合顺序。 - k3b
你应该测试行为,而不是数据结构...DTO 是数据结构,你只需要测试修改它们状态的聚合方法,加入一些行为(验证、if、规则),测试 set 方法是没有意义的...如果你觉得有必要测试它们,也许最好使用像 Project Lombok 这样的库来生成它们... - rascio
3个回答

4
我认为这不是测试领域对象的好方法。根据定义,这些对象封装数据和相关行为,它们应该比仅仅具有getter和setter的愚蠢数据容器更有价值。您将需要像手写对象本身一样手写单元测试。这正是按照DDD理论应该花费时间的地方。
关于数据传输对象(DTO),您可能想查看此问题

我同意关于领域对象测试的观点。还有一个小问题。如果我的一些领域对象只是get/set,它们也可以用作DTO吗?我能否将领域对象用作不同情况下Web服务的DTO。 - user1383012
我不会使用领域对象作为DTO,因为这将使您的Web服务消费者与您的领域对象耦合。当您想要发展您的领域而不影响Web服务客户端时,这将会引起问题。 - Dmitry

2

我的建议:

  • 不要对DTO进行单元测试。这些只是简单的数据结构,具有一堆getter和setter,没有任何行为。getter和setter太过简单,无需进行测试(除非它们封装了某种条件逻辑,但这在DTO中很少出现)。

  • 不要尝试自动化或泛化您的领域对象测试。我看不出测试它们的行为的代码如何被重用,因为它们按定义都具有不同的行为。


0

虽然我认为对DTO进行单元测试有点毫无意义,但基于@Dmitry的答案,我想出了这个类:

[TestClass]
public class PeopleTest
{
    [TestMethod]
    public void OneObjectNull()
    {
        Person obj1 = null;
        var obj2 = new Person
        {
            Id = "101",
            Name = "George Waits",
            Address = "Lake Palmer 10"
        };

        Assert.AreNotEqual(obj1, obj2);
        Assert.AreNotEqual(obj2, obj1);
    }

    [TestMethod]
    public void DeepEqual()
    {
        var obj1 = new Person
        {
            Id = "101",
            Name = "George Waits",
            Address = "Lake Palmer 10"
        };

        var peolpleList1 = new List<Person> { obj1 };
        var peolpleList2 = new List<Person> { obj1 };

        Assert.AreEqual(obj1, obj1);
        CollectionAssert.AreEqual(peolpleList1, peolpleList2);
    }

    [TestMethod]
    public void DeepNotEqual()
    {
        var obj1 = new Person
        {
            Id = "101",
            Name = "George Waits",
            Address = "Lake Palmer 10"
        };

        var obj2 = new Person
        {
            Id = "102",
            Name = "Rachel Smith",
            Address = "Lake Palmer 10"
        };

        var peolpleList1 = new List<Person> { obj1 };
        var peolpleList2 = new List<Person> { obj2 };

        Assert.AreNotEqual(peolpleList1, peolpleList2);

        var group1 = new KeyValuePair<string, List<Person>>("group1", peolpleList1);
        var group2 = new KeyValuePair<string, List<Person>>("group2", peolpleList2);

        Assert.AreNotEqual(group1, group2);
    }

    [TestMethod]
    public void PropertyPositive()
    {
       var obj1 = new Person
        {
            Id = "101",
            Name = "George Waits",
            Address = "Lake Palmer 10"
        };
        obj1.Address = "Parker av 101";

        var obj2 = new Person
        {
            Id = "102",
            Name = "Rachel Smith",
            Address = "Lake Palmer 10"
        };
        obj1.Address = "Listener av 45";

        Assert.AreNotEqual(obj1, obj2);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接