Moq и Entity Framework Core действительно не работают с асинхронными методами? - PullRequest
0 голосов
/ 24 апреля 2018

Я пытаюсь создать тестовое хранилище, используя Moq с EF Core, используя его асинхронные методы (например, AddAsync и SaveChangesAsync), но у меня не было ни малейшего успеха ...

Я нашел много и много постов в блоге (включая вопросы здесь), но у меня ничего не работает.

Например, я буквально скопировал код из этой статьи и попытался реализовать ссылки: [https://fpnotebook.wordpress.com/2017/05/29/asp-net-core-testing-repositories-and-mocking-ef /] но проблема всегда одна и та же, например:

Сообщение: Moq.MockException:
Ожидаемый вызов на макете один раз, но был 0 раз: m => m.AddAsync (It.IsAny (),)
Настройки не настроены.

И то же самое относится к SaveChangesAsync.

Вот пример кода, который я пыталсяреализовать:

// Конфигурация

dbSetMock.Setup(m => m.AddAsync(It.IsAny<T>), It.IsAny<CancellationToken>()))
    .Callback ((T model, CancellationToken token) => {queryableList.Concat (new [] {model})}})
    .Returns ((T model, CancellationToken token) => Task.FromResult((EntityEntry<T>) null));

// Сам тест

[Fact]
public async void AddAsyncTest ()
{
    var mockSet = new Mock <DbSet <Wine >> ();

    var mockContext = new Mock <SQLContext> (_ options);
    mockContext.Setup (m => m.Set <Wine> ()). Returns (mockSet.Object);

    var service = new WineCommandRepository (mockContext.Object);
    await service.Insert (new Wine
    {
        IdWine = 1,
        Name = "Wine1"
    });
    mockContext.Object.SaveChanges ();

    mockSet.Verify (m => m.AddAsync (It.IsAny <Wine>), 
        new CancellationToken ()), Times.Once ());

    mockContext.Verify (m => m.SaveChanges (), Times.Once ());
}

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

Кто-нибудь преодолел это и хаve какой-нибудь пример или рекомендацию поделиться?

1 Ответ

0 голосов
/ 30 апреля 2018

Я подозреваю, что причина, по которой это не работает, состоит в том, что эта проверка (для которой я добавил пропущенные скобки в вопросе и удалила ненужные скобки) никогда не пройдет:

mockSet.Verify(m => m.AddAsync(It.IsAny<Wine>()), new CancellationToken()), Times.Once);

Причина в том, что Verify проверяет, что метод был вызван с предоставленными параметрами, а не чем-то «эквивалентным», а именно тем, что вы сказали (ссылка равна). Однако Verify предоставляется новый экземпляр класса CancellationToken, и невозможно сообщить, что тестируемый код будет возвращать этот точный экземпляр CancellationToken.

Либо вам нужно использовать It.IsAny<CancellationToken>(), либо если вы абстрагируете тестируемый код от явного использования new CancellationToken() и предоставите его через настройку теста, то вы можете передать этот конкретный экземпляр в Verify.

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

...