Как имитировать или подделывать статический метод MongoDB FindAsync () в модульных тестовых случаях .Net, используя MOQ, FakeItEasy или Pose - PullRequest
0 голосов
/ 15 мая 2019

Я пытался смоделировать / подделать статический метод FindAsync () в моих тестовых случаях, используя Wrappers, некоторые концепции Pose. Так как статические методы не могут быть смоделированы или фальсифицированы как обычно. Это не удачно.

Код в слое репозитория, который я хочу объединить в тестовые точки для метода IMongoCollectionExtension.FindAsync ().

Это метод, который я пытаюсь высмеять

 public async Task<MyClass> GetItem(Guid id)
    {
        var filter = Builders<MyClass>.Filter.Eq(m => m.Id, id);
        var result = await _context.MyCollection.FindAsync(filter);
        return result.FirstOrDefault();
    }

Этот FindAsync () указывает на класс STATIC IMongoCollectionExtensions

   public static Task<IAsyncCursor<TDocument>> FindAsync<TDocument>(this IMongoCollection<TDocument> collection, FilterDefinition<TDocument> filter, FindOptions<TDocument, TDocument> options = null, CancellationToken cancellationToken = default(CancellationToken));

Так как он указывает на статический класс и статический метод, я начал писать обертку для макета,

Первый метод с использованием Wrapper:

Это обертка, которую я создал.

  public interface IMongoCollectionExtensionsWrapper
{
    Task<IAsyncCursor<MyClass>> FindAsync<MyClass>(IMongoCollection<MyClass> collection, FilterDefinition<MyClass> filter, FindOptions<MyClass, MyClass> options = null, CancellationToken cancellationToken = default(CancellationToken));
}

public class MongoCollectionExtensionsWrapper : IMongoCollectionExtensionsWrapper
{
    public Task<IAsyncCursor<MyClass>> FindAsync<MyClass>(IMongoCollection<MyClass> collection, FilterDefinition<MyClass> filter, FindOptions<MyClass, MyClass> options = null, CancellationToken cancellationToken = default(CancellationToken))
    {
        return collection.FindAsync(filter, options, cancellationToken);
    }
}

public static class FakeExtensions
{
    public static IMongoCollectionExtensionsWrapper defaultmcExtWrapper = new MongoCollectionExtensionsWrapper();

    public static Task<IAsyncCursor<MyClass>> FindAsync(this IMongoCollection<MyClass> collection, FilterDefinition<MyClass> filter, FindOptions<MyClass, MyClass> options = null, CancellationToken cancellationToken = default(CancellationToken))
    {
        return defaultmcExtWrapper.FindAsync(collection, filter, options, cancellationToken);
    }


}

Так как оболочка не работала должным образом, я проверил бесплатный фреймворк Позы, чтобы высмеивать статические методы. Это тоже не удалось.

Второе испытание с использованием позы

 Shim findshim = Shim.Replace(() => IMongoCollectionExtensions.FindAsync(Is.A<IMongoCollection<MyClass>>(), filter, null, CancellationToken.None)).With(delegate (IMongoCollection<MyClass> mc, FilterDefinition<MyClass> f, FindOptions<MyClass, MyClass> o, CancellationToken ca) { return Task.FromResult(_fakeOutput.FakedObject); });

ПРИМЕЧАНИЕ. _FakeOutput - это фальшивый курсор, содержащий IEnumerable. Работает нормально.

PoseContext.Isolate(() =>
        {
            Task.Run(() =>
            {
                var exp = Task.FromResult(item1);

                var myres = _Repo.GetItem(Id);

                Assert.Equal(exp, myres);
            });

        }, findshim);
        var myres = _Repo.GetItem(Id);

В обоих испытаниях я пытался смоделировать IMongoCollectionExtensions.FindAsync (), но результат (вывод метода, который я хочу протестировать после настройки макета / подделки) в обоих случаях равен нулю и когда я попробовал ниже Утверждение, если метод FindAsync () IMongoCollectionExtension произошел или нет, но он не ударил. Я не понимаю, когда метод, который я хочу выполнить модульным тестом, указывает только на IMongoCollectionExtension.FindAsync (), но он не работает.

fakeIMongoCollExt.CallsTo(x => x.FindAsync(A<IMongoCollection<MyClass>>.Ignored, A<FilterDefinition<MyClass>>.Ignored, null, CancellationToken.None)).MustHaveHappened();

(подпись метода имеет MongoCollections в качестве первого параметра - метод расширения) показывает, что он не попал в этот метод.

Поэтому я попытался проверить MustHaveHappened () для IMongoCollection.FindAsync () (это метод интерфейса, а не метод статического класса, который мы обсуждали выше), который также говорит, что «целью этого вызова является не поддельный объект, который настраивается. «

Я не уверен, как указывает FindAsync (). Как поступить с юнит-тестами. Пожалуйста, дайте мне знать, если у вас есть идеи .. Заранее спасибо ..

IMongoCollections.FindAsync () Mocking

...