Невозможно выполнить модульное тестирование класса с помощью метода, возвращающего RedisResult с помощью StackExchange.Redis. - PullRequest
2 голосов
/ 17 марта 2020

У меня есть простая оболочка для redis для stackexchange:

public interface IRedisClient
{        
    Task<RedisResult> ScriptEvaluate(LuaScript script, object parameters);
}

У меня есть метод, который вызывает ScriptEvaluate

public class Foo
{
    private readonly IRedisClient _client;

    public Foo(IRedisClient client)
    {
        _client = client;
    }

    public void RunScript()
    {
        _client.ScriptEvaluate(LuaScript.Prepare(""), new object());
    }
}

Теперь, когда я использую NSubstitute для насмешки IRedisClient который вводится в Foo и затем вызывается RunScript

public void Test()
{
    _foo = new Foo(Substitute.For<IRedisClient>());
    _foo.RunScript();
}

Я получаю следующую ошибку:

System.TypeLoadException: Метод 'AsBoolean' в типе 'Castle .Proxies.RedisResultProxy 'из сборки' DynamicProxyGenAssembly2, версия = 0.0.0.0, Culture = нейтральный, PublicKeyToken = a621a9e7e5c32e69 'не имеет реализации.

Насколько я вижу Nsubstitute / * Внутренние компоненты 1022 * не могут правильно работать с RedisResult. Мне не удалось найти какие-либо обходные пути.

Можно ли что-то сделать с этим?

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

_client
    .ScriptEvaluate(null, null)
    .ReturnsForAnyArgs(RedisResult.Create((RedisKey)"result"));

Ответы [ 2 ]

1 голос
/ 17 марта 2020

Мне было любопытно, почему насмешка над рефератом RedisResult не была простым решением.

Похоже, это проблема с реализацией NSubstitute.

Использование следующего для повторного создания проблема

public class Foo {
    private readonly IRedisClient _client;

    public Foo(IRedisClient client) {
        _client = client;
    }

    public Task<RedisResult> RunScript() {
        return _client.ScriptEvaluate(LuaScript.Prepare(""), new object());
    }
}

Я смог воспроизвести его с помощью NSubstitute, но смог выполнить тест до конца при использовании другого фреймворка (MOQ)

[TestClass]
public class MyTestClass {
    [TestMethod]
    public async Task Test1() {
        //Arrange
        var expected = RedisResult.Create((RedisKey)"result");
        var _client = Substitute.For<IRedisClient>();

        _client
            .ScriptEvaluate(Arg.Any<LuaScript>(), Arg.Any<object>())
            .Returns(expected);

        var _foo = new Foo(_client);

        //Act
        var actual = await _foo.RunScript();

        //Assert
        actual.Should().Be(expected);
    }

    [TestMethod]
    public async Task Test2() {
        //Arrange
        var expected = RedisResult.Create((RedisKey)"result");
        var _client = Mock.Of<IRedisClient>(_ => _.ScriptEvaluate(It.IsAny<LuaScript>(), It.IsAny<object>()) == Task.FromResult(expected));

        var _foo = new Foo(_client);

        //Act
        var actual = await _foo.RunScript();

        //Assert
        actual.Should().Be(expected);
    }
}
0 голосов
/ 17 марта 2020

RedisResult - это тип abstract, но для обычного сценария ios существуют методы static Create, а также некоторые свойства c, такие как EmptyArray, NullArray и др. c. Я не могу сказать вам, как настроить ваш конкретный слой подделки, но в конечном итоге я ожидал что-то, связанное с RedisResult.Create

...