如何在C#中为create方法编写单元测试?
我想在C#中为add方法编写单元测试。我的方法得到一个dog实体和类型作为参数。这个方法通过我的服务将它添加到数据库中如何在C#中为create方法编写单元测试?,c#,.net,entity-framework,unit-testing,moq,C#,.net,Entity Framework,Unit Testing,Moq,我想在C#中为add方法编写单元测试。我的方法得到一个dog实体和类型作为参数。这个方法通过我的服务将它添加到数据库中 public async Task<ActionResult> Add(Dog dog, string type) { if (ModelState.IsValid) { var d = new Dog(); d.Name = dog.Name; d
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);
}
公共异步任务添加(Dog-Dog,字符串类型)
{
if(ModelState.IsValid)
{
var d=新狗();
d、 Name=dog.Name;
d、 NumOfLegs=dog.NumOfLegs;
d、 BirthdayDate=dog.BirthdayDate;
如果(类型=“妈妈”){
//当狗是妈妈的时候,狗。孩子们有默认的小狗
InitChildrenOfMomDog(狗);
}
dogService.Insert(dog);
返回操作(“主页”);
}
返回视图(dog);
}
我想签入单元测试,我的方法工作正常,默认小狗添加ok到狗,或者如果用户添加了有效(或无效)属性。。。在这一点上我有点困惑。您应该将控制器的代码重构为一个单独的视图模型类。这允许在不与MVC框架交互的情况下直接测试视图模型。看看这个模式 控制器 创建、生成并返回视图模型类。这里应该只有专门限于视图的逻辑,如果有的话,因为它不可直接测试 视图模型 执行视图的所有逻辑操作,例如数据库查询。可以直接测试
代码示例 控制器
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");
}
公共异步任务添加(Dog-Dog,字符串类型)
{
如果(!ModelState.IsValid)
返回视图(dog);
var vm=新的AddDogVM(dogService);
添加(狗,类型);
返回操作(“主页”);
}
查看模型类
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);
}
}
公共类AddDogVM
{
私人IDogService\u dogService
公共AddDogVM(IDogService dogService)
{
_dogService=dogService;
}
公共异步任务添加(狗,字符串类型)
{
var d=新狗();
d、 Name=dog.Name;
d、 NumOfLegs=dog.NumOfLegs;
d、 BirthdayDate=dog.BirthdayDate;
如果(类型=“妈妈”){
InitChildrenOfMomDog(狗);
}
_dogService.Insert(dog);
}
}
测试
public void Test()
{
var dogService = SomeMockingFramework.CreateSubstituteFor<IDogService>();
var vm = new AddDogVM(dogService);
vm.Add(...);
// Assertions
}
公共无效测试()
{
var dogService=SomeMockingFramework.CreateSubstituteFor();
var vm=新的AddDogVM(dogService);
vm.Add(…);
//断言
}
从技术上讲,纯粹的“单元”测试很可能不会测试依赖于Mvc框架的函数-您可能希望了解如何在IsValid
和return
之间提取代码(并了解如何模拟dogService
)。或者你想要一个集成测试来模拟当web客户端调用这个API时会发生什么?是的,我想了解mocking,我读过它,在这种情况下它会很好,但是我很困惑,我应该怎么做。这真的取决于你使用的平台。但是,只要将dogService
声明为某种类型的接口,可以用公开相同函数的模拟类型替换,就不难了。顺便说一句,你是否真的从一个网络客户端测试过它,并确认它正在数据库中存储新的狗?正常情况下,我希望在某处看到一个SaveChanges()
调用(但可能在“Insert”函数中)。我检查了它,并正确地保存到了数据库中。正如您所说,服务是项目中的一个接口。dogService
未在VM中声明。它应该被注射。它是如此的清晰和易懂!非常感谢你!谢谢@OlivierJacot Descombes,我完全忽略了这项服务。