NMock学习系列(三)--- NMock在DDD领域驱动的单元测试中的应用

介绍

领域驱动设计涵盖的知识点比较多,其中代码的架构、设计、编写基本上只占到其中的很小一部分,其它的大部分讲解的是需求的获取方式、项目的管理方式等知识。本篇就是针对这一小部分的知识点位来展开的。所以本篇的学习前提是只需要了解DDD的架构分层即可。

应用场景

DDD领域驱动设计中一旦领域驱动层模型建立完毕,就会产生出数据库持久化的接口即仓储的接口供其它层来做具体实现,所以要想建立领域层的单元测试,就必须实现这些仓储接口或者模拟出这些接口实现。我们可以采用NMock来进行模拟仓储的实现。下面开始学习下代码:

我所建立的领域层的对象都比较简单,结构如下:

其中Entity的Order我们就当他是聚合根吧,IRepository下作为仓储接口,ValueObject为值对象。具体代码如下:

地址Address类:

    public class Address
    {
        public string City { get; set; }
        public string Country { get; set; }
    }

联系方式Contact类:

    public class Contact
    {
        public string Phone { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
    }

返回值Result类:

    public class Result
    {
        public int ID { get; set; }
        public int RowEffect { get; set; }
    }

仓储接口:

    public interface IAddressRepository
    {
        Result SaveAddress(Address address);
    }
    public interface IContactRepository
    {
        Result SaveContact(Contact contact);
    }

聚合根Order类:

    public class Order
    {
        private IContactRepository _contactRp;
        private IAddressRepository _addressRp;

        public Order(IContactRepository contactRp, IAddressRepository addressRp)
        {
            this._contactRp = contactRp;
            this._addressRp = addressRp;
        }

        public int InitOrder(Address address,Contact contact)
        {
            int rowEffect=0;
            if (address != null && !string.IsNullOrEmpty(address.City))
            {
                Result r = _addressRp.SaveAddress(address);
                rowEffect += r.RowEffect;
            }

            if (contact != null && !string.IsNullOrEmpty(contact.Name))
            {
                Result r = _contactRp.SaveContact(contact);
                rowEffect += r.RowEffect;
            }
            return rowEffect;
        }
    }

要想建立InitOrder的单元测试必须要传入两个仓储接口的具体实现类,我们这里使用NMock进行模拟,代码如下:

        [TestMethod]
        public void TestMockDDD()
        {
            MockFactory _factory = new MockFactory();
            Mock<IAddressRepository> addressRp = _factory.CreateMock<IAddressRepository>();
            Mock<IContactRepository> contactRp = _factory.CreateMock<IContactRepository>();

            Order order = new Order(contactRp.MockObject, addressRp.MockObject);

            Address adress = new Address()
            {
                City = "温州",
                Country = "中国"
            };

            Contact contact = new Contact()
            {
                Name = "张三",
                Age = 24,
                Phone = "131111111111"
            };

            Result result = new Result();
            result.ID  = 10000;
            result.RowEffect = 1;

            addressRp.Expects.One
                .Method(d => d.SaveAddress(null))
                .With(adress)
                .Will(Return.Value(result));

            contactRp.Expects.One
                .Method(d => d.SaveContact(null))
                .With(contact)
                .Will(Return.Value(result));

            int count=order.InitOrder(adress, contact);
            Assert.AreEqual(count, 2);
        }

单元测试的内容暂时就先学到这儿了,本系列的源码如下:http://yunpan.cn/cV6wchVc6eveA 访问密码 8d43。

时间: 2024-11-05 12:11:44

NMock学习系列(三)--- NMock在DDD领域驱动的单元测试中的应用的相关文章

NMock学习系列(二)--- NMock在MVP架构系统的单元测试中的应用

介绍 上篇已经学习了NMock的一些基础概念和代码,同时也想到了可能的两个应用场景,本篇开始学习下第一个应用场景---NMock在MVP架构模式下的应用场景.MVP的架构模式概念比较简单,主要是以接口的形式隔离视图与控制器之间的耦合,具体对于MVP模式的介绍请自行搜索学习.本篇接下来的学习前提是读者了解MVP的架构模式,主要明白视图接口的解耦. 应用场景 基于MVP模式的项目往往业务逻辑的编写和视图的建立是分开进行的,视图只需定义出接口供业务控制器进行依赖调用.所以如果在视图还未具体实现的情况下

单元测试学习系列(一)--- NMock对象及数据库模拟介绍

介绍 单元测试是对一个系统的最小可测试单元的检查和验证,系统里关键点位的规则.关键的逻辑均可建立一个单元测试,但是对于一些存在不确定行为对象的测试或者数据库操作的测试不确定因素比较高,初期对此建立的单元测试往往在中后期被废弃掉,原因无非是数据库表的改变或者数据改变或者对象结构改变等等诸多不确定因素的影响.所以要想系统地建立一个单元测试并最大化其作用,我们必须先解决对象行为的不确定性.可以考虑通过依赖接口的方式将这些行为模块化地进行隔离,单元测试只需要模拟这些接口然后注入到需要单元测试的类中,这样

C#进阶系列——DDD领域驱动设计初探(六):领域服务

前言:之前一直在搭建项目架构的代码,有点偏离我们的主题(DDD)了,这篇我们继续来聊聊DDD里面另一个比较重要的知识点:领域服务.关于领域服务的使用,书中也介绍得比较晦涩,在此就根据博主自己的理解谈谈这个知识点的使用. DDD领域驱动设计初探系列文章: C#进阶系列——DDD领域驱动设计初探(一):聚合 C#进阶系列——DDD领域驱动设计初探(二):仓储Repository(上) C#进阶系列——DDD领域驱动设计初探(三):仓储Repository(下) C#进阶系列——DDD领域驱动设计初探

C#进阶系列——DDD领域驱动设计初探(二):仓储Repository(上)

前言:上篇介绍了DDD设计Demo里面的聚合划分以及实体和聚合根的设计,这章继续来说说DDD里面最具争议的话题之一的仓储Repository,为什么Repository会有这么大的争议,博主认为主要原因无非以下两点:一是Repository的真实意图没有理解清楚,导致设计的紊乱,随着项目的横向和纵向扩展,到最后越来越难维护:二是赶时髦的为了“模式”而“模式”,仓储并非适用于所有项目,这就像没有任何一种架构能解决所有的设计难题一样.本篇通过这个设计的Demo来谈谈博主对仓储的理解,有不对的地方还望

[.NET领域驱动设计实战系列]专题十一:.NET 领域驱动设计实战系列总结

一.引用 其实在去年本人已经看过很多关于领域驱动设计的书籍了,包括Microsoft .NET企业级应用框架设计.领域驱动设计C# 2008实现.领域驱动设计:软件核心复杂性应对之道.实现领域驱动设计和Asp.net 设计模式等书,但是去年的学习仅仅限制于看书,当时看下来感觉,领域驱动设计并没有那么难,并且感觉有些领域驱动设计的内容并没有好的,反而觉得有点华而不实的感觉,所以去年也就放弃了领域驱动设计系列的分享了,但是到今年,在博客园看到还是有很多人写领域驱动的文章,以及介绍了领域驱动设计相关的

[.NET领域驱动设计实战系列]专题二:结合领域驱动设计的面向服务架构来搭建网上书店

一.前言 在前面专题一中,我已经介绍了我写这系列文章的初衷了.由于dax.net中的DDD框架和Byteart Retail案例并没有对其形成过程做一步步分析,而是把整个DDD的实现案例展现给我们,这对于一些刚刚接触领域驱动设计的朋友可能会非常迷茫,从而觉得领域驱动设计很难,很复杂,因为学习中要消化一个整个案例的知识,这样未免很多人消化不了就打退堂鼓,就不继续研究下去了,所以这样也不利于DDD的推广.然而本系列可以说是刚接触领域驱动设计朋友的福音,本系列将结合领域驱动设计的思想来一步步构建一个网

DDD领域驱动设计初探(一):聚合

前言:又有差不多半个月没写点什么了,感觉这样很对不起自己似的.今天看到一篇博文里面写道:越是忙人越有时间写博客.呵呵,似乎有点道理,博主为了证明自己也是忙人,这不就来学习下DDD这么一个听上去高大上的东西.前面介绍了下MEF和AOP的相关知识,后面打算分享Automapper.仓储模式.WCF等东西的,可是每次准备动手写点什么的时候,就被要写的Demo难住了,比如仓储模式,使用过它的朋友应该知道,如果你的项目不是按照DDD的架构而引入仓储的设计,那么会让它变得很“鸡肋”,用不好就会十分痛苦,之前

DDD领域驱动设计基本理论知识总结

领域驱动设计之领域模型 加一个导航,关于如何设计聚合的详细思考,见这篇文章. 2004年Eric Evans 发表Domain-Driven Design –Tackling Complexity in the Heart of Software (领域驱动设计),简称Evans DDD.领域驱动设计分为两个阶段: 以一种领域专家.设计人员.开发人员都能理解的通用语言作为相互交流的工具,在交流的过程中发现领域概念,然后将这些概念设计成一个领域模型:由领域模型驱动软件设计,用代码来实现该领域模型:

DDD领域驱动设计仓储Repository

DDD领域驱动设计初探(二):仓储Repository(上) 前言:上篇介绍了DDD设计Demo里面的聚合划分以及实体和聚合根的设计,这章继续来说说DDD里面最具争议的话题之一的仓储Repository,为什么Repository会有这么大的争议,博主认为主要原因无非以下两点:一是Repository的真实意图没有理解清楚,导致设计的紊乱,随着项目的横向和纵向扩展,到最后越来越难维护:二是赶时髦的为了“模式”而“模式”,仓储并非适用于所有项目,这就像没有任何一种架构能解决所有的设计难题一样.本篇