使用Moq对LINQ to SQL CRUD操作进行单元测试 [英] Unit testing LINQ to SQL CRUD operations using Moq

查看:82
本文介绍了使用Moq对LINQ to SQL CRUD操作进行单元测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看过其他问题,但是没有什么能真正满足我的需求……主要是因为我不确定我在寻找什么100%!

I've had a look around at other questions, but nothing really matches what I'm looking for... mainly because I'm not 100% certain on what it is I'm looking for!

目前,我基本上正在开发一个新项目,我已经为数据库实体创建了抽象层,并将DAC设置为存储库.我想对Mock对象使用单元测试,但是我对CRUD(特别是C)操作(我的单元测试类)深有感触:

Basically I'm working on a new project at the moment, I've created my abstraction layer for DB entities and set the DAC to be repositories. I'm wanting to use unit testing for this with Mock objects, however I've hit a intellectual wall with CRUD (specifically C) operations, my unit test class:

[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方法断言失败.现在,我需要做:

My Can_Query_Repository method is successful, however the Can_Add_Person method fails assertion. Now, do I need to do:

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

一如既往,任何帮助/建议都值得赞赏!

As always, any help / advice appreciated!

推荐答案

理想地,您将对它们进行一些集成测试,但是如果您要对其进行单元测试,则可能有多种方法,包括一种在原始问题的评论中没有提到.

Ideally you would do some integration tests for those, but if you want to unit test it, there are possible avenues, including one that wasn't mentioned in the comments of the original question.

第一个. 在测试您的脚本时,可以使用.Verify来检查是否确实调用了Create方法.

The first one. When testing your crud, you can use .Verify to check that the Create methods have really been called.

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

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

With Verify, you can check that the argument was a certain argument, of a certain type and the number of times the method was actually called.

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

The second one. Or if you want to verify the actual objects that have been added in the repository's collection, what you could do is use the .Callback method on your mock.

在测试中,创建一个列表,该列表将接收您创建的对象. 然后,在调用安装程序的同一行上,添加一个回调,该回调将在列表中插入创建的对象.

In your test create a list that will receive the objects you create. Then on the same line where you call your setup add a callback that will insert the created objects in the list.

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

In your asserts you can check the elements in the list, including their properties to make sure the correct elements have been added.

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);

在您的实际示例中,您先创建了该人,然后将其添加到设置中.在这里使用回调方法将不会有用.

Granted in your actual example, you create the person and then add it in the setup. Using the callback method here would not be useful.

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

You could also use this technique to increment a variable to count the number of times it was called.

这篇关于使用Moq对LINQ to SQL CRUD操作进行单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆