c# - 使用 Moq 对 LINQ to SQL CRUD 操作进行单元测试

标签 c# .net linq-to-sql repository moq

我已经查看了其他问题,但没有什么真正符合我正在寻找的...主要是因为我不能 100% 确定我正在寻找的是什么!

基本上我目前正在从事一个新项目,我已经为数据库实体创建了抽象层并将 DAC 设置为存储库。我想使用 Mock 对象对此进行单元测试,但是我在 CRUD(特别是 C)操作方面遇到了障碍,我的单元测试类:

[TestClass]
public class RepositoryTest
{
    private Mock<IPersonRepository> _repository;
    private IList<IPerson> _personStore;

    [TestInitialize()]
    public void Initialize()
    {
        _personStore= new List<IPerson>() {
            new Person() { Name = "Paul" },
            new Person() { Name = "John" },
            new Person() { Name = "Bob" },
            new Person() { Name = "Bill" },
        };

        _repository = new Mock<IPersonRepository>();
        _repository.Setup(r => r.Entirely()).Returns(_personStore.AsQueryable());
    }

    [TestCleanup()]
    public void Cleanup()
    {
        _personStore.Clear();
    }

    [TestMethod()]
    public void Can_Query_Repository()
    {
        IEnumerable<IPerson> people = _repository.Object.Entirely();
        Assert.IsTrue(people.Count() == 4);
        Assert.IsTrue(people.ElementAt(0).Name == "Paul");
        Assert.IsTrue(people.ElementAt(1).Name == "John");
        Assert.IsTrue(people.ElementAt(2).Name == "Bob");
        Assert.IsTrue(people.ElementAt(3).Name == "Bill");
    }

    [TestMethod()]
    public void Can_Add_Person()
    {
        IPerson newPerson = new Person() { Name = "Steve" };

        _repository.Setup(r => r.Create(newPerson));

        // all this Create method does in the repository is InsertOnSubmit(IPerson)
        // then SubmitChanges on the data context
        _repository.Object.Create(newPerson);

        IEnumerable<IPerson> people = _repository.Object.Entirely();
        Assert.IsTrue(people.Count() == 5);
    }
}

我的 Can_Query_Repository 方法是成功的,但是 Can_Add_Person 方法断言失败。现在,我需要做的是:

  1. 设置 Mock 存储库的 .Create 方法以将元素添加到 _personStore?
  2. 做其他类似的事情吗?
  3. 放弃所有希望,因为我想要实现的目标是不可能的,而且我做的一切都是错误的!

一如既往,感谢任何帮助/建议!

最佳答案

理想情况下您会为它们做一些集成测试,但如果您想对其进行单元测试,则有可能的途径,包括原始问题的评论中未提及的途径。

第一个。 测试 crud 时,可以使用 .Verify 来检查是否确实调用了 Create 方法。

mock.Verify(foo => foo.Execute("ping"));

使用 Verify,您可以检查参数是否为特定参数、特定类型以及实际调用该方法的次数。

第二个。 或者,如果您想验证已添加到存储库集合中的实际对象,您可以在模拟中使用 .Callback 方法。

在您的测试中创建一个列表,该列表将接收您创建的对象。 然后在调用设置的同一行添加一个回调,将创建的对象插入列表中。

在您的断言中,您可以检查列表中的元素,包括它们的属性,以确保添加了正确的元素。

var personsThatWereCreated = new List<Person>(); 

_repository.Setup(r => r.Create(newPerson)).Callback((Person p) => personsThatWereCreated.Add(p));

// test code
// ...

// Asserts
Assert.AreEuqal(1, personsThatWereCreated.Count());
Assert.AreEqual("Bob", personsThatWereCreated.First().FirstName);

在您的实际示例中,您创建了这个人,然后将其添加到设置中。在这里使用回调方法是没有用的。

您还可以使用此技术来增加变量以计算它被调用的次数。

关于c# - 使用 Moq 对 LINQ to SQL CRUD 操作进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7599957/

相关文章:

c# - 有什么方法可以为未使用的使用生成编译器警告?

c# - C#中的字节操作

.net - 在 Linq-to-SQL 中模拟多表继承

linq-to-sql - 如何围绕 Membership.CreateUser 封装事务?

c# - 处理点击ListView的子项

c# - 我不喜欢这样……这是在欺骗语言吗?

c# - 如何将resx资源文件变成字典

c# - 使用方法的 MethodHandle 作为键来缓存无参数方法的结果是否安全?

.net - 如何为 MSHTML v9 编译 .dll。我目前收到 100 多个 "MIDL 2035: constant expression expected"错误

c# - Linq 计数(条件)未按预期工作