Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/338.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.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# 先在EF6DB中模拟数据库_C#_Entity Framework_Unit Testing_Testing_Ef Database First - Fatal编程技术网

C# 先在EF6DB中模拟数据库

C# 先在EF6DB中模拟数据库,c#,entity-framework,unit-testing,testing,ef-database-first,C#,Entity Framework,Unit Testing,Testing,Ef Database First,我很难弄清楚如何模拟我的数据库来对我的WebAPI控制器进行单元测试。我找到的所有资源都适用于代码优先EF,但不适用于自动生成上下文的db优先 简单地说,我希望能够调用我的控制器的CRUD操作来对抗我在运行中创建的假数据库,我正在寻找最直接的方法来实现这一点 我试图用它把它放在一起,但无法管理 我的上下文定义为: public partial class MyEntities : DbContext { public MyEntities() : base("name=M

我很难弄清楚如何模拟我的数据库来对我的WebAPI控制器进行单元测试。我找到的所有资源都适用于代码优先EF,但不适用于自动生成上下文的db优先

简单地说,我希望能够调用我的控制器的CRUD操作来对抗我在运行中创建的假数据库,我正在寻找最直接的方法来实现这一点

我试图用它把它放在一起,但无法管理

我的上下文定义为:

public partial class MyEntities : DbContext
{
    public MyEntities()
        : base("name=MyEntities")
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        throw new UnintentionalCodeFirstException();
    }

    public virtual DbSet<Company> Companies { get; set; }
公共部分类myenties:DbContext
{
公共慈善机构()
:base(“name=MyEntities”)
{
}
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
抛出新代码FirstException();
}
公共虚拟数据库集公司{get;set;}
现在我明白了,我需要创建一个IContext,允许对MyEntities进行模拟,但我不知道如何组织它

我尝试过添加以下类,但不知道如何组织这些类

public interface IContext
{
    IObjectSet<Company> Companies { get; }

    void SaveChanges();
}

public class EFContext: IContext
{
    private readonly MyEntities _data;

    public EFContext()
    {
        _data = new MyEntities();
    }

    public IObjectSet<Company> Companies
    {
        get 
        {
            return _data.CreateObjectSet<Company>();
        }
    }

    public void SaveChanges()
    {
        _data.SaveChanges();
    }
}
公共接口IContext
{
IObjectSet公司{get;}
void SaveChanges();
}
公共类EFContext:IContext
{
私有只读MyEntities_数据;
公共环境()
{
_数据=新的MyEntities();
}
公共对象集公司
{
得到
{
返回_data.CreateObjectSet();
}
}
公共void SaveChanges()
{
_data.SaveChanges();
}
}
示例

我想对示例控制器进行单元测试,如果我可以模拟一个数据库进行测试,这将非常容易

public IHttpActionResult Search([FromBody]string query)
    {
        var companies = CompanyRepository.Get().Where(c => c.Name.ToLower().Contains(query.ToLower()));
        var people = PersonRepository.Get().Where(c => c.FirstName.ToLower().Contains(query.ToLower()) || c.LastName.ToLower().Contains(query.ToLower()));

        List<SearchResult> results = new List<SearchResult>();
        foreach(Company company in companies)
            results.Add(new SearchResult { ID = company.ID, Name = company.Name, Type = "Company" });
        foreach (Person person in people)
            results.Add(new SearchResult { ID = person.ID, Name = person.FirstName + " " + person.LastName, Type = "Person" });

        return Ok(results);
    }
公共IHttpActionResult搜索([FromBody]字符串查询)
{
var companys=CompanyRepository.Get(),其中(c=>c.Name.ToLower().Contains(query.ToLower());
var people=PersonRepository.Get().Where(c=>c.FirstName.ToLower().Contains(query.ToLower())| | c.LastName.ToLower().Contains(query.ToLower());
列表结果=新列表();
foreach(公司中的公司)
添加(新的搜索结果{ID=company.ID,Name=company.Name,Type=“company”});
foreach(人对人)
添加(新的搜索结果{ID=person.ID,Name=person.FirstName+“”+person.LastName,Type=“person”});
返回Ok(结果);
}
  • 如何模拟EF数据库第一个上下文以使用测试数据库

  • 于2015年7月11日更新

    因此,我可以看到一些测试:

  • “搜索应获取一次查询不为空的公司”
  • “当查询为空时,搜索不应获取公司”
  • “当查询不为空时,搜索应获取一次人员”
  • “当查询为空时,搜索不应获取人员”
  • “查询为空时,搜索不应添加任何公司”
  • “如果从公司存储库中找到一家公司,则搜索应返回一家公司的结果”
  • “如果从公司存储库中找到两个公司,则搜索应返回两个公司的结果”
  • “当查询为空时,搜索不应返回任何人的结果”
  • “如果从人员存储库中找到一个人,则搜索应返回一个人的结果”
  • “如果从人员存储库中找到两个人,则搜索应返回两个人的结果”
  • 所以首先要考虑的是,这个控制器的“依赖性是什么”。从这个方法中,我可以看到CompanyRepository和PersonRepository。这些都是你想要模拟的东西。也就是说,你没有在这里测试它们或它们的任何功能。你只测试方法中的内容

    您需要更改控制器,以便模拟它们,例如:

    public class MyController : ApiController 
    {
        private ICompanyRepository companyRepository;
        private IPersonRepository personRepository;
    
        public MyController ()
        {
            companyRepository = new CompanyRepository();
            personRepository = new PersonRepository();
        }
    
        public MyController (ICompanyRepository CompanyRepository, IPersonRepository PersonRepository )
        {
            companyRepository = CompanyRepository;
            personRepository = PersonRepository;
        }
    }
    
    然后,您的代码需要引用私有存储库

    public IHttpActionResult Search([FromBody]string query)
    {
        var companies = companyRepository.Get().Where(c => c.Name.ToLower().Contains(query.ToLower()));
        var people = personRepository.Get().Where(c => c.FirstName.ToLower().Contains(query.ToLower()) || c.LastName.ToLower().Contains(query.ToLower()));
    
        List<SearchResult> results = new List<SearchResult>();
        foreach(Company company in companies)
            results.Add(new SearchResult { ID = company.ID, Name = company.Name, Type = "Company" });
        foreach (Person person in people)
            results.Add(new SearchResult { ID = person.ID, Name = person.FirstName + " " + person.LastName, Type = "Person" });
    
        return Ok(results);
    }
    
    公共IHttpActionResult搜索([FromBody]字符串查询)
    {
    var companys=companyRepository.Get(),其中(c=>c.Name.ToLower().Contains(query.ToLower());
    var people=personRepository.Get().Where(c=>c.FirstName.ToLower().Contains(query.ToLower())| | c.LastName.ToLower().Contains(query.ToLower());
    列表结果=新列表();
    foreach(公司中的公司)
    添加(新的搜索结果{ID=company.ID,Name=company.Name,Type=“company”});
    foreach(人对人)
    添加(新的搜索结果{ID=person.ID,Name=person.FirstName+“”+person.LastName,Type=“person”});
    返回Ok(结果);
    }
    
    然后,您的测试看起来像(取决于您使用的测试和模拟框架)。请注意,这是相当粗糙的编码,如果粘贴,将无法工作!:

    [TestClass]
    public class MyControllerTests
    {
        Mock<ICompanyRepository>() mockCompanyRepository = new Mock<ICompanyRepository>()
        Mock<IPersonRepository>() mockPersonRepository = new Mock<IPersonRepository>()
        MyController sut;
    
        Public MyControllerTests ()
        {
            // Create your "System under test" which is your MyController. Pass in your mock repositories to aid your testing.
            sut = new MyController(mockCompanyRepository.Object, mockPersonRepository.Object)
        }
    
        [TestMethod]
        public void SearchShouldGetCompaniesOnceWhereQueryIsNotEmpty
        {
            //Arrange
            var expectedCompanies = new List<Company>{new Company{"Company1"}, new Company{"Company2"}};
            //Setup mock that will return People list when called:
            mockCompanyRepository.Setup(x => x.Get()).Returns(expectedCompanies);
            mockPersonRepository.Setup(x => x.Get()).Returns(new List<Person>())
    
        //Act
        var result = sut.Search("Conway");
    
        //Assert - check the company repository was called once and the result was as expected
        mockCompanyRepository.Verify(x => x.Get(), Times.Once());
    
    OkNegotiatedContentResult<string> conNegResult = Assert.IsType<OkNegotiatedContentResult<string>>(actionResult);
    Assert.Equal("data: [{Name : "Company1"}, {Name : "Company2"}]", conNegResult.Content);
        }
    }
    
    [TestClass]
    公共类MyControllerTests
    {
    Mock()mockCompanyRepository=新建Mock()
    Mock()mockPersonRepository=新建Mock()
    霉菌控制素;
    公共MyControllerTests()
    {
    //创建您的“测试中的系统”,这是您的MyController。传入您的模拟存储库以帮助您进行测试。
    sut=新的MyController(mockCompanyRepository.Object、mockPersonRepository.Object)
    }
    [测试方法]
    公共无效搜索应获取公司,查询不为空
    {
    //安排
    var ExpectedCompanys=新列表{新公司{“Company1”},新公司{“Company2”};
    //调用时将返回人员列表的安装程序模拟:
    mockCompanyRepository.Setup(x=>x.Get()).Returns(expectedcompanys);
    mockPersonRepository.Setup(x=>x.Get()).Returns(new List())
    //表演
    var result=sut.Search(“康威”);
    //断言-检查公司存储库被调用一次,结果与预期一致
    mockCompanyRepository.Verify(x=>x.Get(),Times.Once());
    OkNegotiatedContentResult conNegResult=Assert.IsType(actionResult);
    相等(“数据:[{Name:“Company1”},{Name:“Company2”}]”,connegressult.Content);
    }
    }
    
    您还没有在问题中包含存储库的代码,但是如果您使用上述样式,您应该