似乎无法起订量 EF CodeFirst 4.1。有帮助吗?

2023-12-23

我的任务是评估 codeFirst 并可能用于我们未来的所有项目。 评估基于将 codeFirst 与现有数据库结合使用。

想知道是否可以使用 codeFirst 4.1 来模拟存储库。(没有假货)

这个想法是将存储库注入到服务中并最小起订量存储库。

我一直在网上寻找,但我只找到了一个使用假货的例子。我不想使用假货,我想使用起订量。

我认为我的问题出在 DAL 的架构中。(我想使用 unitOfWork 等。我需要展示一个工作起订量示例)

由于缺乏对 Code First 4.1 的了解,以下是我的尝试(惨败)。 我还上传了一个解决方案,以防万一有人心情好并想更改它。

http://cid-9db5ae91a2948485.office.live.com/browse.aspx/Public%20Folder?uc=1 http://cid-9db5ae91a2948485.office.live.com/browse.aspx/Public%20Folder?uc=1

我愿意接受建议和对我的 Dal 进行全面修改。理想情况下使用 Unity 等。但我稍后会担心。 最重要的是我需要能够嘲笑它。如果无法使用 MOQ,我们将使用 EF 4.1 对该项目进行分类

尝试失败

//CodeFirst.Tests Project
[TestClass]
public class StudentTests
{
    [TestMethod]
    public void Should_be_able_to_verify_that_get_all_has_been_called()
    {
        //todo redo test once i can make a simple one work
        //Arrange
        var repository = new Mock<IStudentRepository>();
        var expectedStudents = new List<Student>();
        repository.Setup(x => x.GetAll()).Returns(expectedStudents);

        //act
        var studentService = new StudentService(repository.Object);
        studentService.GetAll();

        //assert
        repository.Verify(x => x.GetAll(), Times.AtLeastOnce());
    }

}

//CodeFirst.Common Project
public class Student
{
    public int StudentId { get; set; }
    public string Name { get; set; }
    public string Surname { get; set; }
}
public interface IStudentService
{
    IEnumerable<Student> GetAll();
}

//CodeFirst.Service Project
public class StudentService:IStudentService
{
    private IStudentRepository _studentRepository;

    public StudentService()
    {
    }

    public StudentService(IStudentRepository studentRepository)
    {
        _studentRepository = studentRepository;
    }


    public IEnumerable<Student> GetAll()
    {
        //TODO when mocking using moq this will actually call the db as we need a separate class.
        using (var ctx = new SchoolContext("SchoolDB"))
        {
            _studentRepository = new StudentRepository(ctx);
            var students = _studentRepository.GetAll().ToList();
            return students;
        } 
    }
}

//CodeFirst.Dal Project
public interface IRepository<T> where T : class
{
    T GetOne(Expression<Func<T, bool>> predicate);
    IEnumerable<T> GetAll();
    IEnumerable<T> Find(Expression<Func<T, bool>> predicate);
    void Add(T entity);
    void Delete(T entity);
    T Single(Func<T, bool> predicate);
    T First(Func<T, bool> predicate);
}
public class RepositoryBase<T> : IRepository<T> where T : class
{
    private readonly IDbSet<T> _dbSet;

    public RepositoryBase(DbContext dbContext)
    {
        _dbSet = dbContext.Set<T>();
        if (_dbSet == null) throw new InvalidOperationException("Cannot create dbSet ");
    }

    protected virtual IDbSet<T> Query
    {
        get { return _dbSet; }
    }

    public T GetOne(Expression<Func<T, bool>> predicate)
    {
        return Query.Where(predicate).FirstOrDefault();
    }

    public IEnumerable<T> GetAll()
    {
        return Query.ToArray();
    }

    public IEnumerable<T> Find(Expression<Func<T, bool>> predicate)
    {
        return Query.Where(predicate).ToArray();
    }

    public void Add(T entity)
    {
        _dbSet.Add(entity);
    }

    public void Delete(T entity)
    {
        _dbSet.Remove(entity);
    }


    public T Single(Func<T, bool> predicate)
    {
        return Query.Where(predicate).SingleOrDefault();
    }

    public T First(Func<T, bool> predicate)
    {
        return Query.Where(predicate).FirstOrDefault();
    }

}
 public class SchoolContext:DbContext
{
    public SchoolContext(string connectionString):base(connectionString)
    {
        Database.SetInitializer<SchoolContext>(null);
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        //Not sure why I have to do this.Without this when using integration testing
        //as opposed to UnitTests it does not work.
        modelBuilder.Entity<Student>().ToTable("Student");       }


    public DbSet<Student> Students { get; set; }
}
public interface IStudentRepository:IRepository<Student>
{

}
public class StudentRepository : RepositoryBase<Student>, IStudentRepository
{
    public StudentRepository(DbContext dbContext)
        : base(dbContext)
    {
    }

    public IEnumerable<Student> GetStudents()
    {
        return GetAll();
    }
}

再次请随意修改或做任何需要帮助我把东西整合在一起的事情。

非常感谢你的帮助


当我开始使用存储库和工作单元模式时,我使用了类似于this https://stackoverflow.com/questions/4295975/repository-pattern-in-entity-framework-4-when-should-we-dispose/4298173#4298173(它适用于 ObjectContext API,但将其转换为 DbContext API 很简单)。我们通过 MOQ 和 Unity 来使用该实现,没有任何问题。到那时,存储库和工作单元的实现以及注入方法都已经发展。后来我们发现整个这种方法有严重的陷阱,但这已经在我引用的其他问题中讨论过here https://stackoverflow.com/questions/5762846/is-unitofwork-and-genericrepository-pattern-redundant-in-ef-4-1-code-first/5763551#5763551(我强烈建议您浏览这些链接)。

令人惊讶的是,您在评估 EFv4.1 时高度重视模拟和单元测试,同时您定义的服务方法根本不可进行单元测试(通过模拟)。您的服务方法的主要问题是您没有将存储库/上下文作为依赖项传递,因此您无法模拟它。测试您的服务并且不使用真实存储库的唯一方法是使用一些非常先进的方法 https://stackoverflow.com/questions/3642749/looking-for-net-mocking-framework-that-allows-testing-methods-having-non-injecte/3642758#3642758= 用绕道替换模拟和最小起订量(例如 Moles 框架)。

首先,您必须做的是将服务代码替换为:

public class StudentService : IStudentService
{
    private readonly IStudentRepository _studentRepository;

    public StudentService(IStudentRepository studentRepository)
    {
        _studentRepository = studentRepository;
    }

    public IEnumerable<Student> GetAll()
    {
         return _studentRepository.GetAll().ToList();
    }
}

顺便提一句。这是绝对无用的代码和愚蠢的分层示例,不提供任何有用的功能。仅将调用包装到存储库仅表明根本不需要服务,并且不需要对该方法进行单元测试。这里的要点是集成测试GetAll method.

无论如何,如果你想将这种方法与最小起订量结合起来,你会这样做:

[TestClass]
public class StudentsServiveTest
{
    private Mock<IRespository<Student>> _repo;

    [TestInitialize]
    public void Init()
    {
        _repo = new Mock<IRepository<Student>>();
        _repo.Setup(r => r.GetAll()).Returns(() => new Student[] 
            { 
                new Student { StudentId = 1, Name = "A", Surname = "B" },
                new Student { StudentId = 2, Name = "B", Surname = "C" }
            });
    }

    [TestMethod]
    public void ShouldReturnAllStudents()
    {
        var service = new StudentsService(_repo.Object);
        var data = service.GetAll();
        _repo.Verify(r => r.GetAll(), Times.Once());

        Assert.IsNotNull(data);
        Assert.AreEqual(2, data.Count);
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

似乎无法起订量 EF CodeFirst 4.1。有帮助吗? 的相关文章

  • 使用 Maven 对 Android 进行单元测试

    我有一个关于使用 Maven 构建的 android 项目的问题 我们让它运行我们的活动测试 但现在我们需要它来运行单元测试 单元测试与活动测试位于同一项目中 我如何在 pom xml 文件中设置它 这是父 Pom xml 文件
  • 在保存到数据库方法之后,存储库模式应如何更新对象的 ID?

    在内存中创建 POCO 后 我调用存储库对象上的 Save 方法 然后 我需要使用保存操作期间创建的数据库 ID 更新 POCO 我应该使用 ref 传递对象 只需让 save 方法返回 ID 并从调用页面手动更新对象 还是什么 这是一些示
  • 使用 NSURLSession 进行单元测试

    我想为使用共享的方法编写单元测试NSURLSession 特别是 NSURLSessionDataTask下载数据 基本上 我希望目标方法能够接收模拟响应 数据 而不需要互联网连接 模拟这些组件的不太不显眼的方式是什么 我正在考虑填充NSU
  • 如何测试 Flask 开发服务器是否已启动?

    我的 Flask 应用程序上有一个测试装置 它启动开发服务器来测试一些用户交互 对于第一个测试 我想确保服务器已启动 一般而言 无需测试特定响应代码 执行此操作的最佳方法是什么 我希望我能用self assertTrue response
  • 如何模拟类路径上属性文件的存在?

    这肯定是一个常见问题 我有一个像这样的属性文件my settings properties由应用程序类读取 当我编写测试类时 它需要测试可能存在的不同场景my settings properties为了确保最大的代码覆盖率 例如空属性文件
  • C# 压力测试 - 模拟对给定共享资源的多次访问

    如何在 C 单元测试中模拟 压力测试 100 个用户访问给定的共享资源 例如数据库 假设您正在访问真实的数据库 那么您就处于集成测试的范围内 最简单的方法是从多个线程访问资源 例如 Test public void SimpleStress
  • 单元测试:独立测试与代码重复(DRY)

    我正在迈出单元测试的第一步 并且不确定在单元测试中似乎相互矛盾的两个范式 即 每个单元测试都应该是独立的 不依赖于其他单元测试 不要重复自己 更具体地说 我有一个要测试的导入器 导入器具有 导入 功能 获取原始数据 例如 从 CSV 中取出
  • 测试 Spring 端点时如何防止 NestedServletException?

    我在尝试着测试安全配置我的一些端点受到保护 PreAuthorize oauth2 hasScope scope 当使用不具有所需范围的访问令牌通过 Postman 访问此类端点时 将返回以下内容并带有 HTTP 状态代码 403 禁止 e
  • 将文件上传到S3的模拟测试用例

    我们如何模拟文件上传到 S3 我尝试过这样的事情 file mock mock MagicMock spec File name FileMock mock patch storages backends s3boto S3BotoStor
  • 如何模拟 typeorm 连接

    在集成测试中 我使用以下代码片段来创建连接 import Connection createConnection from typeorm ts ignore import options from ormconfig js export
  • 如何知道您的单元测试装置是否“尺寸合适”?

    您如何知道 测试夹具 的尺寸是否合适 我所说的 测试夹具 是指一个包含大量测试的类 我在测试装置中一直注意到的一件事是它们变得有点冗长 鉴于它们也可能不够详细 您如何了解单元测试的大小是否合适 我的假设是 至少在 Web 开发的背景下 您应
  • Seam 和 Mock 有什么区别?

    自从我使用 java 遗留代码以来已经有几个月了 这是我正在处理的一些事情 0 测试覆盖率 巨大的函数有时我什至看到有的代码超过300行 许多私有方法 有时还有静态方法 高度紧密耦合的代码 一开始我很困惑 我发现在遗留系统中使用TDD很难
  • 在某些情况下如何告诉mock调用原始方法?

    我有一个类想要在稍后的测试中进行模拟 class Original function calculate a in test mock this gt getMock Original calculate mock gt expcets t
  • 使用 testify 模拟接口方法两次,输入和输出不同

    如何在 golang 测试中模拟接口方法两次 例如 type myCache interface Get key string data interface error type service struct cache myCache f
  • 如何将 OpenCV 的测试框架与 CMake 结合使用?

    好像 OpenCV 有一个测试框架 https github com Itseez opencv tree ef91d7e8830c36785f0b6fdbf2045da48413dd76 modules ts include opencv
  • UnitTest HttpResponse WriteAsync 和 CopyToAsync

    我想对下一个方法进行单元测试 public static async Task SetResponseBody HttpResponse response string message var originalResponseBody re
  • 包含routeChangeSuccess的AngularJS测试控制器

    我正在尝试创建单元测试来测试导航列表控制器 但在创建测试时遇到问题 这是控制器的代码 navListModule controller NavListCtrl scope NavList function scope NavList sco
  • Moq - 如何对方法中引用的更改进行单元测试

    另一天 另一个问题 我的服务层有以下方法 public MatchViewData CreateMatch string user var matchViewData HasReachedMaxNumberOfMatchesLimit us
  • 尽管极其懒惰,但如何在 Python 中模拟 IMAP 服务器?

    我很好奇是否有一种简单的方法来模拟 IMAP 服务器 例如imaplib模块 在Python中 without做很多工作 是否有预先存在的解决方案 理想情况下 我可以连接到现有的 IMAP 服务器 进行转储 并让模拟服务器在真实的邮箱 电子
  • Cucumber Java 与 Spring Boot 集成 - Spring @Autowired 抛出 NullPointer 异常

    我正在为 Spring boot 应用程序编写 cucumber java 单元测试来测试每个功能 当我与 Spring Boot 集成时 Autowired 类抛出 NullPointer 异常 Spring Boot应用程序类 Spri

随机推荐