Подтвердить что ты не робот

Результат установки для вызова метода расширения

Я пытаюсь Setup вернуть вызов методу расширения и получаю:

SetUp : System.NotSupportedException : Expression references a method that does not belong to the mocked object: m => m.Cache.GetOrStore<String>("CacheKey", () => "Foo", 900)

Кажется, что проблема связана со ссылкой на метод GetOrStore объекта Cache, который является методом расширения.

Код компилируется, но с этим исключением не выполняется.

Что мне нужно сделать, чтобы настроить результат такого метода расширения?

4b9b3361

Ответ 1

Методы расширения не могут быть издевательски похожи на методы экземпляра, поскольку они не определены в вашем издеваемом типе. Они определены в других статических классах. Поскольку вы не можете просто имитировать их, вместо этого вы должны издеваться над всеми методами/свойствами, используемыми методом расширения.

Это пример того, как методы расширения тесно связывают ваш код с другими классами. Независимо от того, что вы делаете, ваш класс зависит от этих статических методов. Вы не можете издеваться над этим и тестировать его изолированно. Я предлагаю рефакторинг вашего кода, чтобы переместить эти методы в свои классы, если внутри есть какая-либо логика.

Ответ 2

Moq не может издеваться над статическими методами, поэтому вы не сможете издеваться над расширением GetOrStore.

Вместо этого просто издевайтесь над методами Get и Insert объекта Cache.

Ответ 3

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

IFixture fixture = new Fixture().Customize(new AutoMoqCustomization());

Mock<ICache> internalCache = new Mock<ICache>();
internalCache.Setup(i => i.Get<String>("CacheKey")).Returns("Foo");

var cacheExtension = typeof(CacheExtensions);
var inst = cacheExtension.GetField("_internalCache", BindingFlags.NonPublic | BindingFlags.Static);
inst.SetValue(cacheExtension, internalCache.Object);

Обратите внимание, что этот код не проверен, но он должен объяснить основную идею.