Модульное тестирование операций CRQ LINQ to SQL с использованием Moq - PullRequest
4 голосов
/ 29 сентября 2011

Я осмотрел другие вопросы, но ничего не соответствует тому, что я ищу ... в основном потому, что я не уверен на 100%, что именно я ищу!

В основном я сейчас работаю над новым проектом, я создал свой уровень абстракции для объектов БД и установил, что ЦАП должен быть репозиторием. Я хочу использовать модульное тестирование для этого с объектами 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. Установите метод .Create репозитория Mock для добавления элемента в _personStore?
  2. Есть что-нибудь похожее?
  3. Оставь все надежды, потому что то, чего я хочу достичь, невозможно, и я все делаю неправильно!

Как всегда, любая помощь / совет приветствуется!

1 Ответ

6 голосов
/ 25 ноября 2011

В идеале вы бы сделали несколько интеграционных тестов для них, но если вы хотите провести его модульное тестирование, есть возможные пути, включая тот, который не был упомянут в комментариях к исходному вопросу.

Первый. При тестировании вашего 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);

В вашем примере вы создаете человека, а затем добавляете его в настройку. Использование метода обратного вызова здесь было бы бесполезным.

Вы также можете использовать эту технику для увеличения переменной, чтобы подсчитать, сколько раз она была вызвана.

...