Как проверить любую из нескольких перегрузок, называемых NSubstitute - PullRequest
0 голосов
/ 21 сентября 2018

Сценарий

Я хотел бы проверить, регистрирует ли компонент (sut) ошибку в определенном состоянии.Конструктор интерфейса ILogger внедряется в компонент, а метод Error имеет 4 перегрузки.

Поэтому я создаю макет ILogger в Arrange и использую его в Act.

Я не должен ожидать, какую перегрузку использует sut, просто хотел бы ожидать и проверить, вызвана ли какая-либо из перегрузок.(это было бы чрезвычайно «белой коробкой» и ожидало гораздо большего, чем функциональная спецификация.)

Вопрос

В настоящее время мой вывод заключается в том, что я не могу использовать .Receivedвместо этого я должен установить обратные вызовы для всех 4 перегрузок и установить переменную внутри них, и в части Assert я исследую эту переменную.

Есть ли какой-нибудь простой способ сделать это, что я пропустил?

(пример)

[TestMethod]
public void ShouldLogErrorIfEmailIsInvalid2()
{
    // Arrange
    var testEmailAddress = "dummy";

    //var mock = new Mock<IEMailValidator>();
    var validator = Substitute.For<IEMailValidator>();
    validator.Validate(Arg.Any<string>()).Returns(false);
    var logger = Substitute.For<ILogger>();

    var sut = new CustomerController(validator, logger);

    var customer = new Customer() { Email = testEmailAddress };

    // Act
    sut.Post(customer);

    // Assert
    // *** Here I do not want to expect a specific overload of Error, instead any of the 4 overloads satisfies the expectation
    logger.Received(1).Error(Arg.Is<string>( m => m.ToLower().Contains("email")), Arg.Any<object>());
}

1 Ответ

0 голосов
/ 22 сентября 2018

NSubstitute не имеет встроенного синтаксиса для этого, но можно запросить все ReceivedCalls() и вручную подтвердить это.

Например:

var errorCalls = logger.ReceivedCalls()
    .Where(x => x.GetMethodInfo().Name == nameof(logger.Error))
    .Where(x => (x.GetArguments()[0] as string).ToLower().Contains("email"));

Assert.AreEqual(1, errorCalls.Count());

Если этоэто то, что вам часто нужно, вы можете реализовать некоторые вспомогательные методы и упаковать их в нечто довольно сжатое, я думаю.(Может быть static void ReceivedCallToAny(this object substitute, string methodName, Func<object[], bool> requiredArgs) с некоторыми помощниками, такими как T GetItemAs<T>(object[] items) для доступа к аргументам?)

...