Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/extjs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用EF SaveChanges对MVC控制器进行单元测试_C#_Asp.net Mvc_Unit Testing_Mocking - Fatal编程技术网

C# 如何使用EF SaveChanges对MVC控制器进行单元测试

C# 如何使用EF SaveChanges对MVC控制器进行单元测试,c#,asp.net-mvc,unit-testing,mocking,C#,Asp.net Mvc,Unit Testing,Mocking,下面是一个带有Post方法的控制器。如何在不将更改保存到数据库的情况下针对CREATE方法编写单元测试 我正试图针对我的控制器编写测试,这样当其他开发人员更改代码时,它就不会破坏我的功能(我在Create方法上有一点功能,现在可以让它保持简单) } 2.)我的UOW看起来像这样: 公共类UnitOfWork:IUnitOfWork { 私有只读主上下文\u上下文 public UnitOfWork(MasterContext context) { _context = context;

下面是一个带有Post方法的控制器。如何在不将更改保存到数据库的情况下针对CREATE方法编写单元测试

我正试图针对我的控制器编写测试,这样当其他开发人员更改代码时,它就不会破坏我的功能(我在Create方法上有一点功能,现在可以让它保持简单)

}

2.)我的UOW看起来像这样:

公共类UnitOfWork:IUnitOfWork { 私有只读主上下文\u上下文

public UnitOfWork(MasterContext context)
{
    _context = context;
}

public UnitOfWork()
{
    _context = new MasterContext();
}

public void SaveChanges()
{
    _context.SaveChanges();
}

private IAdministratorRepository _Repo;

public IAdministratorRepository AdministratorRepository
{
    get
    {
        if (this._Repo == null)
        {
            this._Repo = new IAdministratorRepository(_context);
        }
        return _Repo;
    }
}

3) 我的AdministratorRepository构造函数如下所示:

    private readonly MasterContext _context;

    public AdministratorRepository(MasterContext context)
    {
        _context = context;
    }

您需要能够向控制器中注入假/模拟IUnitOfWork。最简单的方法是在控制器上创建一个内部构造函数,该构造函数接受伪对象,并创建一个属性,该属性创建一个新实例或返回现有实例

private IUnitOfWork _uow;
private IUnitOfWork UnitOfWork
{
    get
    {
        _uow = _uow ?? new UnitOfWork();
        return _uow;
    }
}

public AdministratorController() {}

internal AdministratorController( IUnitOfWork uow )
{
    _uow = uow;
}
您还需要修改MVC项目的AssemblyInfo文件,以使内部构造函数对单元测试项目可见。查一下内部可归因于此

现在在单元测试中,您可以创建伪/模拟对象并将其注入。您没有指明正在使用的模拟框架。我们使用Fakeetisy,所以它类似于:

var uow = A.Fake<IUnitOfWork>();

var controller = new AdministratorController( uow );

A.CallTo( () => uow.SaveChanges() ).MustHaveHappened();
var-uow=A.Fake();
var控制器=新的管理员控制器(uow);
A.CallTo(()=>uow.SaveChanges()).musthaveOccessed();

您应该模拟您的依赖关系。在您的示例中是存储库的AddRecord()。然后,您应该使用预期模型(必须在单元测试方法中设置)测试返回的模型字段。

经典答案是,您没有。你可以抽象出任何类似数据库的东西。然而,我的新想法是,您可以使用SQL CE或SQL Server LocalDB创建一个数据库,并将其转移到您的测试生命周期中。您已经完成了这项艰巨的工作,将数据库访问抽象到一个可模拟的接口后面。只需创建一个模拟所需操作的存根,或者使用模拟框架。如果您有任何直接传递Linq的方法,您将遇到一些问题,因为Linq to Entities的行为与Linq to Object略有不同,这是大多数模拟框架都会使用的。然后您必须调整上述代码以使用MOCK来创建模拟/假/存根IUnitOfWork。就我个人而言,我从未听说过MOCK,因此我不会在细节方面提供太多帮助,但老实说,在这一点上,您应该能够从这里开始,自己了解创建MOCK对象的细节。
var uow = A.Fake<IUnitOfWork>();

var controller = new AdministratorController( uow );

A.CallTo( () => uow.SaveChanges() ).MustHaveHappened();