【问题标题】:How to write unit test for a create method in C#? [closed]如何在 C# 中为 create 方法编写单元测试? [关闭]
【发布时间】:2018-05-17 07:01:44
【问题描述】:

我想在 C# 中为我的 add 方法编写单元测试。我的方法有一个狗实体和类型作为参数。这个方法通过我的服务将它添加到数据库中。

  public async Task<ActionResult> Add(Dog dog, string type)
    {
        if (ModelState.IsValid)
        {
            var d = new Dog();

            d.Name = dog.Name;
            d.NumOfLegs = dog.NumOfLegs;
            d.BirthdayDate = dog.BirthdayDate;

            if(type == "mom"){
              //when the dog is a mom, dog.Childrens got default puppies
              InitChildrenOfMomDog(dog);
            }

            dogService.Insert(dog);

            return RedirectToAction("Home");
        }

        return View(dog);
    }

我想检查单元测试,我的方法工作正常,默认小狗添加到狗身上,或者用户是否添加了有效(或不)属性......我在这一点上有点困惑。

【问题讨论】:

  • 从技术上讲,纯“单元”测试很可能不会测试像这样依赖于 Mvc 框架的函数 - 您可能希望查看提取 IsValidreturn 之间的代码(并且知道如何模拟dogService)。还是您想要一个集成测试来模拟 Web 客户端调用此 API 时会发生什么?
  • 是的,我想了解 mocking,我读过它,在这种情况下会很棒,但我很困惑,我该怎么做。
  • 真的取决于您使用的平台。但只要dogService 被声明为某种接口,可以用暴露相同功能的模拟类型替换,这应该不难。顺便说一句,您实际上是否从 Web 客户端对此进行了测试并确认它在数据库中存储了新的 Dogs?只是通常我希望在某处看到SaveChanges() 调用(但也许它在您的“插入”函数中)。
  • 我检查了它,并且狗正确地保存到了数据库中。正如你所说,服务是项目中的一个接口。

标签: c# .net entity-framework unit-testing moq


【解决方案1】:

您应该将 Controller 的代码重构为单独的视图模型类。这允许直接测试视图模型,而无需与 MVC 框架交互。请参阅MVVM 模式。

控制器 创建、构建并返回一个视图模型类。如果有的话,只有专门限制在视图的逻辑应该在这里,因为它不能直接测试。

视图模型 执行视图的所有逻辑操作,例如数据库查询。可以直接测试测试。


代码示例

控制器

public async Task<ActionResult> Add(Dog dog, string type)
{
    if (!ModelState.IsValid)
        return View(dog);

    var vm = new AddDogVM(dogService);
    vm.Add(dog, type);

    return RedirectToAction("Home");
}

查看模型类

public class AddDogVM
{
    private IDogService _dogService

    public AddDogVM(IDogService dogService)
    {
        _dogService = dogService;
    }

    public async Task<ActionResult> Add(Dog dog, string type)
    {
        var d = new Dog();

        d.Name = dog.Name;
        d.NumOfLegs = dog.NumOfLegs;
        d.BirthdayDate = dog.BirthdayDate;

        if (type == "mom") {
            InitChildrenOfMomDog(dog);
        }

        _dogService.Insert(dog);
    }
}

测试

public void Test()
{
    var dogService = SomeMockingFramework.CreateSubstituteFor<IDogService>();
    var vm = new AddDogVM(dogService);
    vm.Add(...);

    // Assertions
}

【讨论】:

  • dogService 未在 VM 中声明。它应该被注入。
  • 它更清晰,更易于理解!非常感谢!
  • 谢谢@OlivierJacot-Descombes,我完全忽略了这项服务。
猜你喜欢
  • 1970-01-01
  • 2019-02-15
  • 1970-01-01
  • 2021-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-15
  • 2011-11-14
相关资源
最近更新 更多