Исключение выдается при вызове метода расширения из moq, который использует func в качестве параметра - PullRequest
0 голосов
/ 02 мая 2019

У меня проблема с созданием модульного теста для метода, который вызывает статическую функцию, и один из ее параметров - это функция. Проблема по-прежнему возникает, хотя я создал класс-оболочку для вызова статической функции, т.е. расширения i.e, как предлагается в этой статье:

Как использовать Moq для макетирования метода расширения?

Как кто-то предложил, я должен создать интерфейс и класс-обертку, что я и сделал, но я все еще получаю исключение, когда он запускает настройку moq. Моя настройка выглядит следующим образом:

context.Setup(c => new MyExtensionWapper()
   .UpdateCollection<TestObject, int>(
   context.Object,
   databaseCollection,
   detachedCollection,
   o=>o.Id.Value));

Ошибка возникает на o=>o.Id.Value, и класс MyExtensionWapper является функцией Wrapper, которая реализует IExtensions с контрактом UpdateCollection.

Обратите внимание, что моя UpdateCollection является обобщенной функцией, относящейся к Entity Framework, где TEntity является объектом сущности EF & а TKey имеет тенденцию быть Int.

public class MyExtensionWapper : IExtensions
{
    public virtual void UpdateCollection<TEntity, TKey>(IDbContext context, 
        ICollection<TEntity> databaseCollection, 
        ICollection<TEntity> detachedCollection, 
        Func<TEntity, TKey> keySelector)
        where TEntity : class
        where TKey : IEquatable<TKey>
    {
        context.UpdateCollection(databaseCollection, 
        detachedCollection, keySelector);
    }
}

Когда он попадает в moq context.Setup(..., я получаю следующую ошибку:

System.NotSupportedException: 'Unsupported expression: o => o.Id.Value'

Можете ли вы помочь?

Спасибо.

UPDATE-1

Это мой первоначальный вызов, когда я пытался вызвать статический метод (расширение) непосредственно из макета:

context.Setup(c => c.UpdateCollection<TestObject, int>(
databaseCollection,
detachedCollection,
o=>o.Id.Value));

и мой макет создается следующим образом:

context = CreateMock<IDbContext>(MockBehavior.Loose);

Но при вызове я получаю следующую ошибку:

System.NotSupportedException: 'Invalid setup on an extension method:....

Обновление 2

В соответствии с предложением @Johnny, я должен смоделировать интерфейс, поэтому я попробовал следующее, но я получаю ту же ошибку:

Mock<IExtensions> dbExtension;

// Note: Results are the same whether I create the mock with a loose
// behaviour or not.
dbExtension = CreateMock<IExtensions>(MockBehavior.Loose);

dbExtension.Setup(c => new MyExtensionWapper()
    .UpdateCollection<TestObject, int>(
    context.Object,
    databaseCollection,
    detachedCollection,
    o=>o.Id.Value,

Кроме того, вместо того, чтобы вызывать класс-оболочку, я попытался вызвать метод UpdateCollection непосредственно из макета, поскольку он определен в интерфейсе, т.е. c => c.UpdateCollection (databaseCollection, ...), но безрезультатно.

1 Ответ

1 голос
/ 02 мая 2019

Я в итоге заставил его работать, используя предложенный метод @Johnny, который должен был насмехаться над интерфейсом, но мне пришлось внести небольшое изменение в мой макет:

dbExtension.Setup(c => c.UpdateCollection<TestObject, int>(
    context.Object,
    databaseCollection,
    detachedCollection,
    It.IsAny<Func<TestObject, int>>());

Вместо передачи

o=>o.Id.Value

Я не передаю

It.IsAny<Func<TestObject, int>>()

Обратите внимание, что попытка передать It.IsAny<Func<TestObject, int>>() в моем исходном коде, который вызывал класс-оболочку, не сработала и выдает следующее исключение:

System.InvalidOperationException: 'No coercion operator is defined 
between types 'Extensions.MyExtensionWapper' and 'Moq.Mock'.'
...