Дразнящий функционал - PullRequest
1 голос
/ 17 марта 2019

У меня есть несколько случаев использования, когда я передаю Funcs некоторым методам. То, что я пытаюсь сделать, это создать расширение или помощник с Moq, который позволяет моим тестам легко создавать функции. Целью этого помощника является

  1. Легко определить функцию с ожидаемым входом и фиксированным выходом
  2. Проверка должна завершиться неудачей, если функция не вызывается
  3. Проверка должна завершиться неудачей, если функция вызвана с неправильным вводом
  4. Использование It.IsAny<TInput>() должно работать как в любом макете

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

public static Func<TIn, TOut> FixedFunc<TIn, TOut>(this MockRepository repo, TIn expectedInput, TOut fixedOutput)
{
    var verifier = repo.Create<IInvokable<TIn, TOut>>(MockBehavior.Strict);

    verifier.Setup(m => m.Invoke(expectedInput))
        .Returns(fixedOutput);

    return input => verifier.Object.Invoke(input);
}

public static Func<TIn, TOut> FixedFunc<TIn, TOut>(this MockRepository repo, TOut fixedOutput)
{
    var verifier = repo.Create<IInvokable<TIn, TOut>>(MockBehavior.Strict);

    verifier.Setup(m => m.Invoke(It.IsAny<TIn>()))
        .Returns(fixedOutput);

    return input => verifier.Object.Invoke(input);
}

public interface IInvokable<TIn, TOut>
{
    TOut Invoke(TIn input);
}

а вот и тесты

[Fact] // succeeds
public void MockFunc_SameObject_RetursResult()
{
    var expectedInput= new object();
    var expectedOutput = 2;

    var repo = new MockRepository(MockBehavior.Strict);
    var function = repo.FixedFunc(exptecedInput, expectedOutput);

    var output = function(expectedInput);
    Assert.Equal(expectedOutput, output);

    repo.VerifyAll();
}

[Fact]
// Fails with the following exception:
// "Moq.MockException: IInvokable`2.Invoke(object) invocation failed with mock behavior Strict.
// All invocations on the mock must have a corresponding setup."
public void MockFunc_IsAny_RetursResult()
{
    var exptecedInput = new object();
    var expectedOutput = 2;

    var repo = new MockRepository(MockBehavior.Strict);
    var function = repo.FixedFunc(It.IsAny<object>(), expectedOutput);

    var output = function(exptecedInput);
    Assert.Equal(expectedOutput, output);

    repo.VerifyAll();
}

[Fact] // succeeds
public void MockFunc_WithAny_RetursResult()
{
    var expectedOutput = 2;

    var repo = new MockRepository(MockBehavior.Strict);
    var function = repo.FixedFunc<object, int>(expectedOutput);

    var output = function(new object());
    Assert.Equal(expectedOutput, output);

    repo.VerifyAll();
}

Я не понимаю, как использование It.IsAny работает для FixedFunc <TOut>, но не для FixedFunc <TIn, TOut>

1 Ответ

0 голосов
/ 17 марта 2019

Обратите внимание на одну вещь, если вы оцените It.Any<object>(), результат будет null.В случае Func<TIn, TOut> вы фактически создаете настройки для:

verifier.Setup(m => m.Invoke(null)).Returns(fixedOutput);

, а затем вызываете его с помощью var exptecedInput = new object();.Во время VerifyAll, когда moq пытается оценить и сопоставить аргументы, он не может этого сделать, потому что null != new object().


Вы либо хотите вызвать метод также с помощью It.Any<object>(), либо изменить дизайн расширения.передать Expression и зарегистрировать настройку с Expression вместо определенного объекта.

[Fact] // This will pass
public void MockFunc_IsAny_RetursResult()
{
    var expectedOutput = 2;

    var repo = new MockRepository(MockBehavior.Strict);
    var function = repo.FixedFunc(It.IsAny<object>(), expectedOutput);

    var output = function(It.IsAny<object>());

    Assert.Equal(expectedOutput, output);
    repo.VerifyAll();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...