• 系列教程
  • 开发文档
abp+vue-element-admin搭建个人网站
abp+vue-element-admin搭建个人网站
vs code 编辑器基础使用专题
vs code 编辑器基础使用专题
网站SEO优化专题,让搜索引擎对网站更有亲和力
网站SEO优化专题,让搜索引擎对网站更有亲和力
.NET Core基于abp vnext 开发个人网站【专题】
.NET Core基于abp vnext 开发个人网站【专题】
C# linq如何使用,无法识别方法等问题专场
C# linq如何使用,无法识别方法等问题专场
MySQL常见面试题
MySQL常见面试题
.NET/.NET Core面试题
.NET/.NET Core面试题
  • MySQL LCASE() 函数

    MySQLLCASE()函数将指定字符串转为小写并返回。LCASE()函数是LOWER()函数的别名。如果想将字符串转换为大写,请使用UCASE()或者UPPER()函数。LCASE()语法这里是MySQLLCASE()函数的语法:LCASE(str)参数str必需的。被处理的字符串。返回值LCAS

  • MySQL JSON_TYPE() 函数

    MySQLJSON_TYPE()函数返回一个给定的JSON值的类型。JSON_TYPE()语法这里是MySQLJSON_TYPE()的语法:JSON_TYPE(json_value)参数json_value必需的。一个JSON值。返回值JSON_TYPE()函数返回一个utf8mb4字符串,它代表了

  • MySQL UUID_SHORT() 函数

    MySQLUUID_SHORT()函数返回一个在一定条件下具有唯一性的短的通用标识符(64位无符号整数)。UUID_SHORT()函数与UUID()函数返回值不同并具有不同的唯一性属性。UUID_SHORT()语法这里是MySQLUUID_SHORT()函数的语法:UUID_SHORT()参数MyS

  • .NET Core(C#)使用NPOI获取Excel包含空的单元格和设置列(column)为自动尺寸

    NPOI是POI项目的.NET版本。POI是一个开源的Java读写Excel、WORD等微软OLE2组件文档的项目,使用NPOI你就可以在没有安装Office或者相应环境的机器上对WORD/EXCEL文档进行读写。NPOI是构建在POI3.x版本之上的,它可以在没有安装Office的情况下对Word/Excel文档进行读写操作。本文主要介绍.NETCore(C#)中,使用NPOI获取有空单元格或者缺失单元格的Excel(.xls,xlsx)文件和设置列为自动尺寸方法,以及相关的示例代码。

  • MySQL 索引提示:USE INDEX

    MySQL查询优化器是MySQL数据库服务器的一个组件,它为SQL语句制定最佳执行计划。MySQL优化器通常根据索引基数进行决策。有时候,虽然你创建了索引,但是你的SQL语句却不一定使用索引。这是因为MySQL查询优化器的做出了它认为的更优的选择。MySQL允许您使用USEINDEX语句建议查询优化

  • 2)对接管理后台的前端vue项目&用户登录

    上一章 进行到了让项目跑起来,本章将对接管理后台的前端vue项目&用户登录 项目用到的管理后台UI框架是vue-element-admin vue2版本,下载地址:https://github.com/PanJiaChen/vue-element-admin/tree/i18n 将下载的文件放到,你想放的位置,如

  • 小程序展示3D模型

    公用js文件在我账号下载里有可以去下载一下<canvasid="webgl"canvas-id="webgl"type="webgl"bindtouchstart="touchStart"bindtouchmove="touchMove"bindtouchend="touchEnd"bindtouchcancel="touchCancel"style="width:750rpx;height:720rpx"></canvas>这里也加了手势滑动,

  • .NET Core(C#)html和url字符串编解码方法(HtmlDecode、HtmlEncode、UrlDecode、UrlEncode)

    本文主要介绍.NETCore(C#)中,封装HtmlDecode、HtmlEncode、UrlDecode、UrlEncode成工具类,并且兼容.NETFramework的方法,以及相关的示例代码。

CSS|HTML   小程序开发   运维部署  开发技巧 推荐阅读

  • 微信小程序的wxml、wxss、js、json的理解 微信小程序的wxml、wxss、js、json的理解 微信小程序的基础学习(2)小程序的有些语言,有时候按照官方的解释来理解非常的吃力,会把初学者搞得很懵很难受,不知道从何下手!文件夹下四个文件的理解:文件中文解释(个人理解).wxml小程序页面视图例如人的脸.wxss小程序页面视图修饰例如修饰人脸的胖瘦肤白.js小程序逻辑层例如人脸的神经,其作用就是控制整个人脸的运行.json小程序全局配置其作用配置导航栏的文字、背景颜色、页面底部tabbar等wxml----小程序的脸面官方解释:WXML 文章阅读
  • MySQL 索引提示:USE INDEX MySQL 索引提示:USE INDEX MySQL查询优化器是MySQL数据库服务器的一个组件,它为SQL语句制定最佳执行计划。MySQL优化器通常根据索引基数进行决策。有时候,虽然你创建了索引,但是你的SQL语句却不一定使用索引。这是因为MySQL查询优化器的做出了它认为的更优的选择。MySQL允许您使用USEINDEX语句建议查询优化 文章阅读
  • MySQL UPPER() 函数 MySQL UPPER() 函数 MySQLUPPER()函数将指定字符串转为大写并返回。UCASE()函数是UPPER()函数的别名。如果想将字符串转换为小写,请使用LCASE()或者LOWER()函数。UPPER()语法这里是MySQLUPPER()函数的语法:UPPER(str)参数str必需的。被处理的字符串。返回值UPPE 文章阅读

文章|阅读

  • 目录ABP入门系列(1)——通过模板创建MAP版本项目ABP入门系列(2)——领域层创建实体ABP入门系列(3)——领域层定义仓储并实现ABP入门系列(4)——创建应用服务ABP入门系列(5)——展现层实现增删改查ABP入门系列(6)——定义导航菜单ABP入门系列(7)——分页实现ABP入门系列(8)——Json格式化ABP入门系列(9)——权限管理ABP入门系列(10)——扩展AbpSessionABP入门系列(11)——编写单元测试ABP入门系列(12)——如何升级Abp并调试源码ABP入门系列(13)——Redis缓存用起来ABP入门系列(14)——应用BootstrapTable表格插件ABP入门系列(15)——创建微信公众号模块ABP入门系列(16)——通过webapi与系统进行交互ABP入门系列(17)——使用ABP集成的邮件系统发送邮件ABP入门系列(18)——使用领域服务ABP入门系列(19)——使用领域事件ABP入门系列(20)——使用后台作业和工作者ABP入门系列(21)——切换MySQL数据

    .Net

  • 首先来看下[Fact]的简单示例:public>Class1{[Fact]publicvoidPassingTest(){Assert.Equal(4,Add(2,2));}[Fact]publicvoidFailingTest(){Assert.Equal(5,Add(2,2));}intAdd(intx,inty){returnx+y;}}其中xUnit.Net提供了三种继承于DataAttribute的特性([InlineData]、[ClassData]、[PropertyData])用于为[Theory]标记的参数化测试方法传参。下面是使用这三种特性传参的实例:InlineDataExamplepublic>StringTests1{[Theory,InlineData("goodnightmoon","moon",true),InlineData("helloworld","hi",false)]publicvoidContains(stringinput,stringsub,boolexpected){varactual=input.Contains(sub);Assert.Equal(expected,actual);}}PropertyDataExamplepublic>StringTests2{[Theory,PropertyData("SplitCountData")]publicvoidSplitCount(stringinput,intexpectedCount){varactualCount=input.Split('').Count();Assert.Equal(expectedCount,actualCount);}publicstaticIEnumerable<object[]>SplitCountData{get{//Orthiscouldreadfromafile.:)returnnew[]{newobject[]{"xUnit",1},newobject[]{"isfun",2},newobject[]{"totestwith",3}};}}}ClassDataExamplepublic>{[Theory,ClassData(typeof(IndexOfData))]publicvoidIndexOf(stringinput,charletter,intexpected){varactual=input.IndexOf(letter);Assert.Equal(expected,actual);}}public>:IEnumerable<object[]>{privatereadonlyList<object[]>_data=newList<object[]>{newobject[]{"helloworld",'w',6},newobject[]{"goodnightmoon",'w',-1}};publicIEnumerator<object[]>GetEnumerator(){return_data.GetEnumerator();}IEnumeratorIEnumerable.GetEnumerator(){returnGetEnumerator();}}2.4.Shouldly(断言框架)Shouldly提供的断言方式与传统的Assert相比更实用易懂。对比一下就明白了:Assert.That(contestant.Points,Is.EqualTo(1337));//Expected1337butwas0contestant.Points.ShouldBe(1337);//contestant.Pointsshouldbe1337butwas0首先上写法上更清晰易懂,第二当测试失败时,提示消息也更清楚直接。同样,想对Shouldly有更对了解,请直接访问Shouldly官方链接。2.5.测试基类XxxTestBase首先来看看代码:publicabstract>LearningMpaAbpTestBase:AbpIntegratedTestBase<LearningMpaAbpTestModule>{privateDbConnection_hostDb;privateDictionary<int,DbConnection>_tenantDbs;//onlyusedfordbpertenantarchitectureprotectedLearningMpaAbpTestBase(){//SeedinitialdataforhostAbpSession.TenantId=null;UsingDbContext(context=>{newInitialHostDbBuilder(context).Create();newDefaultTenantCreator(context).Create();});//SeedinitialdatafordefaulttenantAbpSession.TenantId=1;UsingDbContext(context=>{newTenantRoleAndUserBuilder(context,1).Create();});LoginAsDefaultTenantAdmin();UsingDbContext(context=>newInitialDataBuilder().Build(context));}protectedoverridevoidPreInitialize(){base.PreInitialize();UseSingleDatabase();//UseDatabasePerTenant();}privatevoidUseSingleDatabase(){_hostDb=DbConnectionFactory.CreateTransient();LocalIocManager.IocContainer.Register(Component.For<DbConnection>().UsingFactoryMethod(()=>_hostDb).Life>从该段代码中我们可以看出该测试基类继承自AbpIntegratedTestBase<T>。在PreInitialize()方法中指定了为租户创建单一数据库还是多个数据库。_hostDb=DbConnectionFactory.CreateTransient();是Effort提供的方法用来创建的DbConnection(数据库连接)。然后将其使用单例的模式注册到IOC容器中,这样在测试中,所有的数据库连接都将使用Effort为我们创建的数据库连接。在构造函数中主要做了两件事,预置了初始数据和种子数据,并以默认租户Admin登录。至此我们对abp为我们默认创建的测试项目有了一个大概的认识。下面我们就开始实战阶段。3.单元测试实战3.1.理清要测试的方法逻辑我们以应用服务层的TaskAppService的CreateTask方法为例,创建单元测试。先来看看该方法的代码:publicintCreateTask(CreateTaskInputinput){//WecanuseLogger,it'sdefinedinApplicationService>.Info("Creatingataskforinput:"+input);//判断用户是否有权限if(input.AssignedPersonId.HasValue&&input.AssignedPersonId.Value!=AbpSession.GetUserId())PermissionChecker.Authorize(PermissionNames.Pages_Tasks_AssignPerson);vartask=Mapper.Map<Task>(input);intresult=_taskRepository.InsertAndGetId(task);//只有创建成功才发送邮件和通知if(result>0){task.CreationTime=Clock.Now;if(input.AssignedPersonId.HasValue){task.AssignedPerson=_userRepository.Load(input.AssignedPersonId.Value);varmessage="Youhavabeenassignedonetaskintoyourtodolist.";//TODO:需要重新配置QQ邮箱密码//SmtpEmailSenderemailSender=newSmtpEmailSender(_smtpEmialSenderConfig);//emailSender.Send("ysjshengjie@qq.com",task.AssignedPerson.EmailAddress,"NewTodoitem",message);_notificationPublisher.Publish("NewTask",newMessageNotificationData(message),null,NotificationSeverity.Info,new[]{task.AssignedPerson.ToUserIdentifier()});}}该方法主要有三步,第一步判断权限,第二步保存数据库并返回Id,第三步发送通知。3.2.创建单元测试类并注入依赖创建TaskAppSerice_Tests类并继承自XxxTestBase类,并注入需要的依赖。public>TaskAppService_Tests:LearningMpaAbpTestBase{privatereadonlyITaskAppService_taskAppService;publicTaskAppService_Tests(){_taskAppService=Resolve<TaskAppService>();}}3.3.创建单元测试方法第一个方法我们应该测试Happypath(即测试方法的默认场景,没有异常和错误信息)。[Fact]publicvoidShould_Create_New_Task_WithPermission(){//Arrange//LoginAsDefaultTenantAdmin();//基类的构造函数中已经以默认租户Admin登录。varinitalCount=UsingDbContext(ctx=>ctx.Tasks.Count());vartask1=newCreateTaskInput(){Title="TestTask",Description="TestTask",State=TaskState.Open};vartask2=newCreateTaskInput(){Title="TestTask2",Description="TestTask2",State=TaskState.Open};//ActinttaskResult1=_taskAppService.CreateTask(task1);inttaskResult2=_taskAppService.CreateTask(task2);//AssertUsingDbContext(ctx=>{taskResult1.ShouldBeGreaterThan(0);taskResult2.ShouldBeGreaterThan(0);ctx.Tasks.Count().ShouldBe(initalCount+2);ctx.Tasks.FirstOrDefault(t=>t.Title=="TestTask").ShouldNotBe(null);vartask=ctx.Tasks.FirstOrDefault(t=>t.Title=="TestTask2");task.ShouldNotBe(null);task.State.ShouldBe(TaskState.Open);});}在这里啰嗦一下单元测试的AAA原则:Arrange:为测试做准备工作Act:运行实际测试的代码Assert:断言,校验结果再说明一下单元测试的方法推荐命名规则:some_result_occurs_when_doing...回到我们这个测试方法。Arrange阶段我们先以Admin登录(Admin具有所有权限),然后获取数据库中初始Task的数量,再准备了两条测试数据。Act阶段,直接调用TaskAppService的CreateTask方法。Assert阶段:首先判断CreateTask的返回值大于0;再判断现在数据库的数量是否增加了2条;再校验数据库中是否包含创建的Task,并核对Task的状态。3.4.预置数据在进行测试的时候,我们肯定需要一些测试数据,以便我们进行合理的测试。在基础设施层,我们有专门的SeedData目录用来预置种子数据。但是进行单元测试的测试数据不应该污染实体数据库,所以直接在SeedData目录预置数据就不太现实。3.4.1.创建TestDataBuilder所以,我们就直接在测试项目中,新建一个TestDatas文件夹来管理测试种子数据。然后创建TestDataBuilder类,通过该类来统一创建所需的测试数据。(注意,需要修改下类中的_context类型为你自己项目对应的DbContext)namespaceLearningMpaAbp.Tests.TestDatas{public>TestDataBuilder{privatereadonlyLearningMpaAbpDbContext_context;privatereadonlyint_tenantId;publicTestDataBuilder(LearningMpaAbpDbContextcontext,inttenantId){_context=context;_tenantId=tenantId;}publicvoidCreate(){_context.DisableAllFilters();//newTestUserBuilder(_context,_tenantId).Create();//newTestTasksBuilder(_context,_tenantId).Create();_context.SaveChanges();}}}然后修改我们的测试基类XxxTestBase,在构造函数调用我们新建的TestDataBuilder的Create()方法。newTestDataBuilder(context,1).Create();,如下图:3.4.2.创建Task测试数据创建TestTasksBuilder,如下:(注意,需要修改下类中的_context类型为你自己项目对应的DbContext)namespaceLearningMpaAbp.Tests.TestDatas{public>TestTasksBuilder{privatereadonlyLearningMpaAbpDbContext_context;privatereadonlyint_tenantId;publicTestTasksBuilder(LearningMpaAbpDbContextcontext,inttenantId){_context=context;_tenantId=tenantId;}publicvoidCreate(){for(inti=0;i<8;i++){vartask=newTask(){Title="TestTask"+i,Description="TestTask"+i,CreationTime=DateTime.Now,State=(TaskState)newRandom().Next(0,1)};_context.Tasks.Add(task);}}}}然后再在TestDataBuild中调用该类的Create()的方法即可。newTestTasksBuilder(_context,_tenantId).Create();3.5.Runthetest(单元测试跑起来)UTPassed喜闻乐见的绿色,单元测试通过。3.6.完善测试用例单元测试中我们仅仅测试HappyPath是远远不够的。因为毕竟我们只是测试了正常的正确场景。为了提高单元测试的覆盖度,我们应该针对代码可能出现的异常问题进行测试。还拿我们刚刚的CreateTask方法为例,其中第二步有一个验证权限操作,当用户没有权限的时候,Task应该不能创建并抛出异常。那我们就针对无权限的场景补充一个单元测试吧。3.6.1.预置数据无权限简单,直接创建一个新用户登录就ok了。但为了用户复用,我们还是在种子数据中预置测试用户吧。回到我们的TestDatas目录,创建TestUserBuilder,来预置测试用户。namespaceLearningMpaAbp.Tests.TestDatas{///<summary>///预置测试用户(无权限)///</summary>public>TestUserBuilder{privatereadonlyLearningMpaAbpDbContext_context;privatereadonlyint_tenantId;publicTestUserBuilder(LearningMpaAbpDbContextcontext,inttenantId){_context=context;_tenantId=tenantId;}publicvoidCreate(){vartestUser=_context.Users.FirstOrDefault(u=>u.TenantId==_tenantId&&u.UserName=="TestUser");if(testUser==null){testUser=newUser{TenantId=_tenantId,UserName="TestUser",Name="TestUser",Surname="Test",EmailAddress="test@defaulttenant.com",Password=User.DefaultPassword,IsEmailConfirmed=true,IsActive=true};_context.Users.Add(testUser);}}}}然后再在TestDataBuild中调用该类的Create()的方法即可。newTestUserBuilder(_context,_tenantId).Create();3.6.2.完善单元测试///<summary>///若没有分配任务给他人的权限,创建的任务指定给他人,则任务创建不成功。///</summary>[Fact]publicvoidShould_Not_Create_New_Order_AssignToOrther_WithoutPermission(){//ArrangeLoginAsTenant(Tenant.DefaultTenantName,"TestUser");//获取admin用户varadminUser=UsingDbContext(ctx=>ctx.Users.FirstOrDefault(u=>u.UserName==User.AdminUserName));varnewTask=newCreateTaskInput(){Title="TestTask",Description="TestTask",State=TaskState.Open,AssignedPersonId=adminUser.Id//TestUser创建Task并分配给Admin};//Act,AssertAssert.Throws<AbpAuthorizationException>(()=>_taskAppService.CreateTask(newTask));}当用户无权限时,将抛出Abp封装的AbpAuthorizationException(未授权异常)。UTPassed单元测试用例,就讲这两个,剩下的自己动手完善吧。源码中已经覆盖测试,可供参考。4.总结这篇文章中主要梳理了Abp中如何进行单元测试,以及依赖的xUnit、Effort、Shouldly框架的用法。并基于以上内容的总结,进行了单元测试的实战演练。相信看完此篇文章的总结,对你在Abp中进行单元测试,有所裨益

    .Net

  • 千万级别的表分页查询非常慢,如何改进?

    在实际的软件系统开发过程中,随着使用的用户群体越来越多,表数据也会随着时间的推移,单表的数据量会越来越大。以订单表为例,假如每天的订单量在 4 万左右,那么一个月的订单量就是 120 多万,一年就是 1400 多万,随着年数的增加和单日下单量的增加,订单表的数据量会越来越庞大,订单数据的查询不会像最初那样简单快速,如果查询关键字段没有走索引,会直接影响到用户体验,甚至会影响到服务是否能正常运行!

    Database

  • 想要自己制作微信小程序,但是不知道需要什么样的技术才能开发微信小程序。那么今天小编就来简介绍一下。制作小程序的方式有几种?第一种就是自己通过编写小程序代码进开发制作,第二种就找专业的小程序开发公司进行开发制作小程序。第三种方式是不需要技术代码也不需要程序开发公司。自己就可以使用拖拽式组件出自己的小程序。通俗明白的一讲就像搭积木一样搭建自己的小程序。下面介绍自己过并写小程序代码开发制作小程序需要的技术支持有哪些?对于有比较成熟的开发经验的工程师来说,小程序开发的知识对他们来说不是难事,多看几下就能明白。

    小程序

  • 调用微信API获取小程序URL Link

    调用微信API获取小程序URLLink过程需要的微信小程序API版本构建一个切面获取微信小程序API提供的Service接口创建一个从微信API获取URLLink的Service接口请求参数过程需要的微信小程序API版本现在微信开源的API,从版本为4.1.8.B开始才提供了获取URLLink的API,所以在我们的项目中需要引进版本为4.1.8.B的maven依赖,在pom.xml中加入对应的依赖即可:<dependency><groupId&g

    小程序

  • 2021目标期望没达到预期,今天过后所有的期待与努力无最爱、无例外、往事清零,一起跨入2022,续上昨日的期

    Life

  • vscode设置中文

    1打开扩展面板打开Vscode,点击扩展图标,打开侧边栏“EXTENSIONS”面板。2下载安装中文简体插件搜索框中键入“Chinese”检索出“中文简体”点击“install”。3重新启动Vscode中文简体插件安装完成后,点击右下角“restart”按钮重新启动Vscode。4Vscode设置为中文重新打开Vscode,可以看到界面就会变为汉字界面。END

    开发技巧

2023年 03月26日

周日