Невозможно настроить имитируемую Redis IDatabase с помощью MoqC#

Место общения программистов C#
Ответить
Anonymous
 Невозможно настроить имитируемую Redis IDatabase с помощью Moq

Сообщение Anonymous »

Это мой тест кэша в программе:
[Fact]
public async Task Cache_Works_Correctly()
{
const string testkey = "69";
const string testvalue = "Nice";

var mockDatabase = new Mock();

mockDatabase.Setup(_ => _.StringGet(CacheConstants.NamePrefix + testkey, CommandFlags.None)).Returns(testvalue);

var mockMultiplexer = new Mock();
mockMultiplexer.Setup(_ => _.IsConnected).Returns(false);

mockMultiplexer
.Setup(_ => _.GetDatabase(It.IsAny(), It.IsAny()))
.Returns(mockDatabase.Object);

var cache = new CacheStore(mockMultiplexer.Object.GetDatabase(), new Mock().Object);

Assert.Equal(testvalue, await cache.GetValueAsync(testkey));
}

Проблема проявляется в этой строке:
mockDatabase.Setup(_ => _.StringGet(CacheConstants.NamePrefix + testkey, CommandFlags.None)).Returns(testvalue);

Когда я запускаю тест, я получаю исключение аргумента:
Message: 
System.ArgumentException : Unsupported expression: (string)_.StringGet((RedisKey)"SummaryAPI_69", CommandFlags.None)

Stack Trace: 
ExpressionExtensions.Split(LambdaExpression expression, Boolean allowNonOverridableLastProperty) line 159
Mock.SetupRecursive[TSetup](Mock mock, LambdaExpression expression, Func`4 setupLast, Boolean allowNonOverridableLastProperty) line 645
Mock.Setup(Mock mock, LambdaExpression expression, Condition condition) line 500
Mock`1.Setup[TResult](Expression`1 expression) line 452
UniversalCacheTests.Cache_Works_Correctly() line 23
--- End of stack trace from previous location ---

Похоже, что Moq не может настроить функцию StringGet() в IDatabase, но она отлично работает, например, с ToString(). Есть ли способ сделать то, что я хочу?
Это моя функция CacheStore.GetValueAsync, которую я хочу протестировать, имитируя IDatabase:
public async Task GetValueAsync(string key)
{
key = CacheConstants.NamePrefix + key;
this._logger.LogInformation($"Getting {key} from cache.");

var jsonData = await Task.Run(() => this._database.StringGet(key));

if (jsonData == RedisValue.Null)
{
return default;
}

return JsonSerializer.Deserialize(jsonData!);
}

Я попробовал проверить, могу ли я настроить другие функции IDatabase, и это сработало! Похоже, Moq просто не может работать с этими конкретными функциями. Глядя на код, проблема возникает в функции Moq .Split(). Написано, что это
Splits an expression such as m => m.A.B(x).C[y] = z into a chain of parts
that can be set up one at a time:
m => m.A
... => ....B(x)
... => ....C
... => ...[y] = z

Почему IDatabase.StringGet для него проблематичен? Не знаю
Вот как это выглядит в коде:
internal static Stack Split(this LambdaExpression expression, bool allowNonOverridableLastProperty = false)
{
Debug.Assert(expression != null);

var parts = new Stack();

Expression remainder = expression.Body;
while (CanSplit(remainder))
{
Split(remainder, out remainder, out var part, allowNonOverridableLastProperty: allowNonOverridableLastProperty && parts.Count == 0);
parts.Push(part);
}

if (parts.Count > 0 && remainder is ParameterExpression)
{
return parts;
}
else
{
throw new ArgumentException(
string.Format(
CultureInfo.CurrentCulture,
Resources.UnsupportedExpression,
remainder.ToStringFixed()));
}


Подробнее здесь: https://stackoverflow.com/questions/790 ... -using-moq
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»