C# 如何使用Moq绕过数据层?

C# 如何使用Moq绕过数据层?,c#,asp.net-mvc,unit-testing,moq,C#,Asp.net Mvc,Unit Testing,Moq,我正在学习使用Moq测试我的控制器,但我不确定如何绕过来自控制器的数据层调用。假设我有一个如下的方法。我将采取什么方法来测试这样一个简单的控制器 [HttpPost] public ActionResult SomeController(SomeModel model) { if(ModelState.IsValid) { // Perform some manipulation on modeldata model.Value++;

我正在学习使用Moq测试我的控制器,但我不确定如何绕过来自控制器的数据层调用。假设我有一个如下的方法。我将采取什么方法来测试这样一个简单的控制器

[HttpPost]
public ActionResult SomeController(SomeModel model)
{
    if(ModelState.IsValid)
    {
        // Perform some manipulation on modeldata
        model.Value++;

        // Upload Model, Get ID
        model.Id = MyDataLayer.UploadToDb(model);
    }
    return View(model);
}
大概是这样的:

interface IMyDataLayer 
{
    int UploadToDb(SomeModel model);
}
class MyDataLayer : IMyDataLayer 
{
    public int UploadToDb(SomeModel model)
    {
        // Implementation ...
    }
}
class MyController : Controller
{
    private readonly IMyDataLayer _datalayer;
    public MyController(IMyDataLayer datalayer)
    {
        _datalayer = _datalayer;
    }

    [HttpPost]
    public ActionResult SomeAction(SomeModel model)
    {
        if(ModelState.IsValid)
        {
            // Perform some manipulation on modeldata
            model.Value++;

            // Upload Model, Get ID
            model.Id = _datalayer.UploadToDb(model);
        }
        return View(model);
    }
}

然后可以使用Moq创建IMyDataLayer的模拟

我使用moq实现了KiwiPet的解决方案,如下所示

[TestMethod()]
public void MyTestMethod()
{
    // Create test input data
    SomeModel TestModel = new SomeModel();
    TestModel.Value = 1;

    // Create mocked data layer
    var FakeDataLayer = new Mock<IMyDataLayer>();
    FakeDataLayer.Setup(x => x.UploadToDb(It.IsAny<SomeModel>()).Returns(TestValueIWantReturned);

    // Create controller using fake data service
    var controller = new MyController(FakeDataLayer.Object);

    // Controller function call
    var result = controller.SomeAction() as ViewResult;

    // Assert stuff
    Assert.IsNotNull(result);
    Assert.IsNotNull(result.Model);
    // ...

}
[TestMethod()]
公共void MyTestMethod()
{
//创建测试输入数据
SomeModel TestModel=新的SomeModel();
TestModel.Value=1;
//创建模拟数据层
var FakeDataLayer=new Mock();
Setup(x=>x.UploadToDb(It.IsAny()).Returns(TestValueIWantReturned);
//使用伪数据服务创建控制器
var controller=newmycontroller(FakeDataLayer.Object);
//控制器函数调用
var result=controller.SomeAction()作为ViewResult;
//断言材料
Assert.IsNotNull(结果);
Assert.IsNotNull(result.Model);
// ...
}

您需要使用接口抽象出数据层。并将数据层的实现注入控制器的CONSTRUCTOR中。然后,实现可以是moq版本,也可以是实际实现引用HotFuzz(指向@KiwiPiet):“他说了什么”.在提供的示例中,
MyDataLayer
是静态的还是局部变量?@Nkosi
MyDataLayer
将是类库中的静态函数。dll@lloyd好的,然后按照已经给出的答案重构代码,使其更易于单元测试。具有静态依赖关系使代码难以单独测试。一次您将代码从静态依赖项中分离出来,现在您可以自由地对依赖项进行建模,以便于进行单元测试。展示一个创建建模并将其注入SUTOk的示例,他们认为这会对OP有所帮助。他们问如何使用MOQ进行此操作,不是吗?您所做的是向他们展示了如何重构代码以允许依赖项dency注射,不一定用MOQ怎么做