DDD实战进阶第一波(七):开发一般业务的大健康行业直销系统(实现产品上下文接口与测试)

前一篇文章我们介绍了如何将创建产品的领域逻辑与产品的持久化仓储通过上架产品的用例组织起来,完成了一个功能。在实际的项目中,多种前端的形态比如PC Web、

微信小程序、原生APP等要调用后端的功能,通常要将后端的功能包装成RESTFUL风格,这样前端就可以使用Http Get或Post方式调用后端的功能,所以这篇文章我们先来完成后端

的Asp.net Core WebApi,通过WebApi将上架产品的功能暴露出去。

实现上下产品接口:

[Produces("application/json")]
    [Route("api/Product")]
    public class ProductController : Controller
    {
        ServiceLocator servicelocator = new ServiceLocator();
        [HttpPost]
        [Route("AddProduct")]
        public ResultEntity<bool> AddProduct([FromBody] AddProductSPUDTO addproductspudto)
        {
            var result = new ResultEntity<bool>();
            var productdbcontext = servicelocator.GetService<IProductContext>();
            var irepository = servicelocator.GetService<IRepository>(new ParameterOverrides { { "context", productdbcontext } });
            var iproductrepository=servicelocator.GetService<IProductRepository>(new ParameterOverrides { { "context", productdbcontext } });
            var addproductspuusecase = new AddProductSPUUseCase(irepository,iproductrepository);
            try
            {
                result = addproductspuusecase.AddProduct(addproductspudto);
                result.IsSuccess = true;
                result.Count = 1;
                result.Msg = "上架产品成功!";
            }
            catch(Exception error)
            {
                result.ErrorCode = 100;
                result.Msg = error.Message;
            }
            return result;
        }
    }

1.首先大家看到接口层是非常薄的一层,它并不包含业务逻辑和数据访问,它只是初始化一些对象,然后完成应用服务的调用,返回前端所需要的格式的对象。

2.产品数据访问上下文、仓储接口、产品上下文仓储接口等需要通过依赖注入框架来获取特定的实现类,依赖注入框架可以采用Asp.net Core自带的,也可以采用Unity等框架。这里略去了依赖注入框架

的具体实现,可以在公众号内查看。

3.如果在调用应用服务可能抛出异常时,需要详细指明每个catch与抛出的内容。

当后端接口完成后,作为后端开发人员,我们需要写单元测试来完成对后端接口的调用,并尝试得到期望的结果。我们在这里采用MSTest,你也可以使用XUnit。

上架产品单元测试:

HttpClient httpclient;       

        [TestMethod]
        public void AddProductTest()
        {
            httpclient = new HttpClient();
            var addproductspudto = new AddProductSPUDTO();
            addproductspudto.SPUName = "XXX石榴露";
            addproductspudto.SPUDesc = "XXX精华石榴露,用于养生";
            addproductspudto.SKUSpecs = new List<string>();
            addproductspudto.SKUSpecs.Add("每瓶50毫升");
            addproductspudto.SKUSpecs.Add("每瓶100毫升");
            addproductspudto.SKUUnits = new List<string>();
            addproductspudto.SKUUnits.Add("瓶");
            addproductspudto.SKUUnits.Add("瓶");
            addproductspudto.SKUPvs = new List<decimal>();
            addproductspudto.SKUPvs.Add(120);
            addproductspudto.SKUPvs.Add(300);
            addproductspudto.SKUDealerPrices = new List<decimal>();
            addproductspudto.SKUDealerPrices.Add(3000);
            addproductspudto.SKUDealerPrices.Add(4000);
            var fs = new FileStream(@"c:\test.jpg", FileMode.Open, FileAccess.Read);
            var imgbytes = new byte[fs.Length];
            fs.Read(imgbytes, 0, Convert.ToInt32(fs.Length));
            fs.Close();
            addproductspudto.SKUImages = new List<byte[]>();
            addproductspudto.SKUImages.Add(imgbytes);
            addproductspudto.SKUImages.Add(imgbytes);

            string json = JsonConvert.SerializeObject(addproductspudto);
            HttpContent httpcontent = new StringContent(json);
            httpcontent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
            var response = httpclient.PostAsync("http://localhost:2209/api/Product/AddProduct", httpcontent).Result;
            var responsevalue = response.Content.ReadAsStringAsync().Result;
            var responsemsg = JsonConvert.DeserializeObject<ResultEntity<bool>>(responsevalue).Msg;
            Assert.AreEqual("上架产品成功!", responsemsg);
        }
[TestMethod]
        public void AddProductTest()
        {
            httpclient = new HttpClient();
            var addproductspudto = new AddProductSPUDTO();
            addproductspudto.SPUName = "XXX面膜";
            addproductspudto.SPUDesc = "XXX面膜,用于护肤";
            addproductspudto.SKUSpecs = new List<string>();
            addproductspudto.SKUSpecs.Add("每盒5张");
            addproductspudto.SKUSpecs.Add("每盒10张");
            addproductspudto.SKUUnits = new List<string>();
            addproductspudto.SKUUnits.Add("盒");
            addproductspudto.SKUUnits.Add("盒");
            addproductspudto.SKUPvs = new List<decimal>();
            addproductspudto.SKUPvs.Add(200);
            addproductspudto.SKUPvs.Add(350);
            addproductspudto.SKUDealerPrices = new List<decimal>();
            addproductspudto.SKUDealerPrices.Add(5000);
            addproductspudto.SKUDealerPrices.Add(8000);
            var fs = new FileStream(@"c:\test1.jpg", FileMode.Open, FileAccess.Read);
            var imgbytes = new byte[fs.Length];
            fs.Read(imgbytes, 0, Convert.ToInt32(fs.Length));
            fs.Close();
            addproductspudto.SKUImages = new List<byte[]>();
            addproductspudto.SKUImages.Add(imgbytes);
            addproductspudto.SKUImages.Add(imgbytes);

            string json = JsonConvert.SerializeObject(addproductspudto);
            HttpContent httpcontent = new StringContent(json);
            httpcontent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
            var response = httpclient.PostAsync("http://localhost:2209/api/Product/AddProduct", httpcontent).Result;
            var responsevalue = response.Content.ReadAsStringAsync().Result;
            var responsemsg = JsonConvert.DeserializeObject<ResultEntity<bool>>(responsevalue).Msg;
            Assert.AreEqual("上架产品成功!", responsemsg);
        }

有了单元测试,我们后端开发人员就可以验证是否后端接口与整个用例是否是正常的,另外单元测试也可以作为每日自动构建的一部分。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏张善友的专栏

.NET 4 System.Threading.Barrier 类

在Visual Studio 2010 and .NET Framework 4 Training Kit中有个System.Threading.Barrier...

2349
来自专栏大内老A

我的WCF之旅(7):面向服务架构(SOA)和面向对象编程(OOP)的结合——如何实现Service Contract的继承

当今的IT领域,SOA已经成为了一个非常时髦的词,对SOA风靡的程度已经让很多人对SOA,对面向服务产生误解。其中很大一部分人甚至认为面向服务将是面向对象的终结...

1885
来自专栏草根专栏

使用两种方法让 ASP.NET Core 实现遵循 HATEOAS 结构的 RESTful API

HATEOAS(Hypermedia as the engine of application state)是 REST 架构风格中最复杂的约束,也是构建成熟 ...

54511
来自专栏GreenLeaves

C# CultureInfo中常用的InvariantCulture

本文参考自CultureInfo中重要的InvariantCulture,纯属读书笔记,加深记忆 1、CultureInfo的InvariantCulture的...

2178
来自专栏blackheart的专栏

[C#6] 8-异常增强

0. 目录 C#6 新增特性目录 1. 在catch和finally块中使用await 在C#5中引入一对关键字await/async,用来支持新的异步编程模型...

1985
来自专栏walterlv - 吕毅的博客

使用 C# 代码创建快捷方式文件

发布于 2015-04-07 04:48 更新于 2018-08...

1931
来自专栏智能大石头

老瓶装新酒 - C#调用WM手机发送短信(源码)

一些系统,需要能够发送短信,量很小,平均每日10条。 运营商平台太贵,白名单很严格,小额只能发省内; 各短信平台有各种限制,大事件前后会关闭; 飞信以前可以用W...

2275
来自专栏木宛城主

深入浅出三层架构

这几天看了不少三层架构的资料,整理整理 ——故写篇博文谈谈自己的看法。 三层架构概念: 三层架构(3-tier application) 通常意义上的三层架构就...

2415
来自专栏岑玉海

WF追忆

  前一阵子学习了一下工作流,现在写个总结记录一下这个过程。要弄工作流,首先就要有个界面来画图,做web的,没办法,只能选择javascript和silverl...

2846
来自专栏草根专栏

从头编写 asp.net core 2.0 web api 基础框架 (5) EF CRUD

Github源码地址:https://github.com/solenovex/Building-asp.net-core-2-web-api-starter-...

4006

扫码关注云+社区

领取腾讯云代金券