ABP单元测试

发表于:2018-9-30 10:26

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:*Hunter    来源:51testing采编

分享:
  如前所述,我们从SimpleTaskSystemTestBase继承。 在单元测试中,我们应该创建要测试的对象。 在构造函数中,我使用LocalIocManager(依赖注入管理器)来创建一个ITaskAppService(它创建了TaskAppService,因为它实现了ITaskAppService)。 以这种方式,我摆脱了创建依赖关系的模拟实现。
  Should_Create_New_Tasks是测试方法。 它使用xUnit的Fact属性进行装饰。 因此,xUnit了解这是一种测试方法,它运行该方法。
  在测试方法中,我们通常遵循AAA模式,包括三个步骤:
  Arrange(安排): 准备测试
  Act(行为): 运行SUT(被测软件 - 实际测试代码)
  Assert(断言): 检查并验证结果
  在Should_Create_New_Tasks方法中,我们将创建两个任务,一个将被分配给Thomas More。 所以,我们的三个步骤是:
  Arrange: 我们从数据库获取该人(Thomas More),以获取数据库中的Id和当前任务数量(另外,我们在构造函数中创建了TaskAppService)。
  Act: 我们正在使用TaskAppService.CreateTask方法创建两个任务。
  Assert: 我们正在检查任务计数是否增加2.我们还尝试从数据库获取创建的任务,以查看它们是否正确插入数据库。
  在这里,UsingDbContext方法可以帮助我们直接使用DbContext。 如果此测试成功,我们了解如果我们提供有效的输入,CreateTask方法可以创建任务。 此外,存储库正在工作,因为它将Tasks插入数据库。
  要运行测试,我们通过选择TEST \ Windows \ Test Explorer打开Visual Studio测试资源管理器:
   
  然后我们点击测试资源管理器中的“全部运行”链接。 它在解决方案中找到并运行所有测试:
   
  如上所示,我们的第一个单元测试通过。恭喜! 如果测试或测试代码不正确,测试将失败。 假设我们已经忘记将赋值赋给给某人(要测试它,注释掉TaskAppService.CreateTask方法中的相关行)。 当我们运行测试时,它将失败:
   
  Shouldly库使得失败的消息更清晰。 它也使写入断言变得容易。 比较xUnit的Assert.Equal与Shouldly的ShouldBe扩展方法:
  Assert.Equal(thomasMore.Id, task2.AssignedPersonId); //Using xunit's Assert
  task2.AssignedPersonId.ShouldBe(thomasMore.Id); //Using Shouldly
  我认为第二个更容易和自然地写和阅读。 应该有很多其他的扩展方法,使我们的生活更轻松。 看到它的文档。
  四、测试异常
  我想为CreateTask方法创建第二个测试。 但是,这次输入无效:
  [Fact]
  public void Should_Not_Create_Task_Without_Description()
  {
  //说明未设置
  Assert.Throws<AbpValidationException>(() => _taskAppService.CreateTask(new CreateTaskInput()));
  }
  我希望CreateTask方法抛出AbpValidationException,如果我没有设置描述创建任务。 因为在CreateTaskInput DTO类中将描述属性标记为必需(请参阅源代码)。 如果CreateTask引发异常,则此测试成功,否则失败。 注意; 验证输入和抛出异常是由ASP.NET Boilerplate基础架构完成的。
  五、在测试中使用存储库
  我将测试从一个人到另一个人分配一个任务:
  //试图将Isaac Asimov的任务分配给Thomas More
  [Fact]
  public void Should_Change_Assigned_People()
  {
  //我们可以使用存储库而不是DbContext
  var taskRepository = LocalIocManager.Resolve<ITaskRepository>();
  //获取测试数据
  var isaacAsimov = GetPerson("Isaac Asimov");
  var thomasMore = GetPerson("Thomas More");
  var targetTask = taskRepository.FirstOrDefault(t => t.AssignedPersonId == isaacAsimov.Id);
  targetTask.ShouldNotBe(null);
  //运行 SUT
  _taskAppService.UpdateTask(
  new UpdateTaskInput
  {
  TaskId = targetTask.Id,
  AssignedPersonId = thomasMore.Id
  });
  //检查结果
  taskRepository.Get(targetTask.Id).AssignedPersonId.ShouldBe(thomasMore.Id);
  }

  在这个测试中,我使用ITaskRepository执行数据库操作,而不是直接使用DbContext。 您可以使用这些方法之一或混合。
  六、测试异步方法
  我们也可以使用xUnit来测试异步方法。 请参阅写入以测试PersonAppService的GetAllPeople方法的方法。 GetAllPeople方法是异步的,所以测试方法也应该是异步的:
  [Fact]
  public async Task Should_Get_All_People()
  {
  var output = await _personAppService.GetAllPeople();
  output.People.Count.ShouldBe(4);
  }

  七、概要
  在本文中,我想显示简单的测试项目开发ASP.NET Boilerplate应用程序框架。 ASP.NET Boilerplate为实现测试驱动开发提供了良好的基础设施,或者简单地为您的应用程序创建了一些单元/集成测试。
  Effort库提供了一个与EntityFramework工作良好的假数据库。 只要您使用EntityFramework和LINQ执行数据库操作,它就可以工作。 如果你有一个存储过程并且要测试它,Effort不工作。 对于这种情况,我建议使用LocalDB。

   上文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理。
22/2<12
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号