[ABP教程]第四章 集成测试

Web应用程序开发教程 - 第三章: 集成测试

Copy
//[doc-params] { "UI": ["MVC","NG"], "DB": ["EF","Mongo"] }

{{
if UI == "MVC"
UI_Text="mvc"
else if UI == "NG"
UI_Text="angular"
else
UI_Text="?"
end
if DB == "EF"
DB_Text="Entity Framework Core"
else if DB == "Mongo"
DB_Text="MongoDB"
else
DB_Text="?"
end
}}

关于本教程#

在本系列教程中, 你将构建一个名为 Acme.BookStore 的用于管理书籍及其作者列表的基于ABP的应用程序. 它是使用以下技术开发的:

  • {{DB_Text}} 做为ORM提供程序.
  • {{UI_Value}} 做为UI框架.

本教程分为以下部分:

下载源码#

本教程根据你的UIDatabase偏好有多个版,我们准备了两种可供下载的源码组合:

解决方案中的测试项目#

这一部分涵盖了 服务器端 测试. 解决方案中有多个测试项目:

bookstore-test-projects-v2

每个项目用于测试相关的应用程序项目.测试项目使用以下库进行测试:

测试项目配置为使用 SQLite内存 作为数据库. 创建一个单独的数据库实例并使用数据种子系统进行初始化种子数据,为每个测试准备一个新的数据库.

{{else if DB=="Mongo"}}

Mongo2Go库用于模拟MongoDB数据库. 创建一个单独的数据库实例并使用数据种子系统进行初始化种子数据,为每个测试准备一个新的数据库.

{{end}}

添加测试数据#

如果你已经按照第一部分中的描述创建了数据种子贡献者,则相同的数据也在测试中可用. 因此你可以跳过此部分. 如果你尚未创建种子贡献者,可以使用 BookStoreTestDataSeedContributor 来为要在以下测试中使用的相同数据提供种子.

测试 BookAppService#

Acme.BookStore.Application.Tests 项目中创建一个名叫 BookAppService_Tests 的测试类:

Copy
using System.Threading.Tasks; using Shouldly; using Volo.Abp.Application.Dtos; using Xunit; namespace Acme.BookStore.Books { {{if DB=="Mongo"}} [Collection(BookStoreTestConsts.CollectionDefinitionName)]{{end}} public class BookAppService_Tests : BookStoreApplicationTestBase { private readonly IBookAppService _bookAppService; public BookAppService_Tests() { _bookAppService = GetRequiredService<IBookAppService>(); } [Fact] public async Task Should_Get_List_Of_Books() { //Act var result = await _bookAppService.GetListAsync( new PagedAndSortedResultRequestDto() ); //Assert result.TotalCount.ShouldBeGreaterThan(0); result.Items.ShouldContain(b => b.Name == "1984"); } } }
  • 测试方法 Should_Get_List_Of_Books 直接使用 BookAppService.GetListAsync 方法来获取用户列表,并执行检查.
  • 我们可以安全地检查 "1984" 这本书的名称,因为我们知道这本书可以在数据库中找到,我们已将其添加到种子数据中.

新增测试方法,用以测试创建一个合法book实体的场景:

Copy
[Fact] public async Task Should_Create_A_Valid_Book() { //Act var result = await _bookAppService.CreateAsync( new CreateUpdateBookDto { Name = "New test book 42", Price = 10, PublishDate = System.DateTime.Now, Type = BookType.ScienceFiction } ); //Assert result.Id.ShouldNotBe(Guid.Empty); result.Name.ShouldBe("New test book 42"); }

新增测试方法,用以测试创建一个非法book实体失败的场景:

Copy
[Fact] public async Task Should_Not_Create_A_Book_Without_Name() { var exception = await Assert.ThrowsAsync<AbpValidationException>(async () => { await _bookAppService.CreateAsync( new CreateUpdateBookDto { Name = "", Price = 10, PublishDate = DateTime.Now, Type = BookType.ScienceFiction } ); }); exception.ValidationErrors .ShouldContain(err => err.MemberNames.Any(mem => mem == "Name")); }
  • 由于 Name 是空值, ABP 抛出一个 AbpValidationException 异常.

最终的测试类如下所示:

Copy
using System; using System.Linq; using System.Threading.Tasks; using Shouldly; using Volo.Abp.Application.Dtos; using Volo.Abp.Validation; using Xunit; namespace Acme.BookStore.Books { {{if DB=="Mongo"}} [Collection(BookStoreTestConsts.CollectionDefinitionName)]{{end}} public class BookAppService_Tests : BookStoreApplicationTestBase { private readonly IBookAppService _bookAppService; public BookAppService_Tests() { _bookAppService = GetRequiredService<IBookAppService>(); } [Fact] public async Task Should_Get_List_Of_Books() { //Act var result = await _bookAppService.GetListAsync( new PagedAndSortedResultRequestDto() ); //Assert result.TotalCount.ShouldBeGreaterThan(0); result.Items.ShouldContain(b => b.Name == "1984"); } [Fact] public async Task Should_Create_A_Valid_Book() { //Act var result = await _bookAppService.CreateAsync( new CreateUpdateBookDto { Name = "New test book 42", Price = 10, PublishDate = System.DateTime.Now, Type = BookType.ScienceFiction } ); //Assert result.Id.ShouldNotBe(Guid.Empty); result.Name.ShouldBe("New test book 42"); } [Fact] public async Task Should_Not_Create_A_Book_Without_Name() { var exception = await Assert.ThrowsAsync<AbpValidationException>(async () => { await _bookAppService.CreateAsync( new CreateUpdateBookDto { Name = "", Price = 10, PublishDate = DateTime.Now, Type = BookType.ScienceFiction } ); }); exception.ValidationErrors .ShouldContain(err => err.MemberNames.Any(mem => mem == "Name")); } } }

打开测试资源管理器(测试 -> Windows -> 测试资源管理器)并执行所有测试:

bookstore-appservice-tests

恭喜你, 绿色图标表示测试已成功通过!

下一章#

查看本教程的下一章.

posted @   LandWind  阅读(337)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 一文读懂知识蒸馏
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示
CONTENTS