WithArgumentsForConstructor с A <string>.That.Contains - PullRequest
1 голос
/ 14 апреля 2020

Я хотел бы проверить, вызывает ли выполнение метод со строкой, содержащей заданную часть И экземпляр класса, который содержит (в своем конструкторе) часть данной строки.

[TestMethod]
public void TestMethod1()
{
    // Arrange
    var fakeLogger = A.Fake<ILogger>();
    var loggerExecutor = new LoggerExecutor(fakeLogger);

    // Act
    loggerExecutor.Log();

    // Assert
    A.CallTo(() => fakeLogger.Error(A<string>.That.Contains("string")).MustHaveHappenedOnceExactly();
    A.CallTo(() => fakeLogger.Error(
        A.Fake<LogLine>(x => x.WithArgumentsForConstructor(() => A<string>.That.Contains("LogLine"))))
    ).MustHaveHappenedOnceExactly();
}

public class LoggerExecutor
{
    private readonly ILogger _logger;

    public LoggerExecutor(ILogger logger)
    {
        _logger = logger;
    }

    public void Log()
    {
        _logger.Error("With string parameter");
        _logger.Error(new LogLine("With LogLine parameter"));
    }
}

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

System.InvalidOperationException: An argument constraint, such as That, Ignored, or _, cannot be nested in an argument.
at FakeItEasy.Expressions.ExpressionArgumentConstraintFactory.ArgumentConstraintExpressionVisitor.VisitMember(MemberExpression node)

Мне следует попробовать с поддельным объектом, чтобы избежать повторения всей строки в тестах.

LogLine класс:

public class LogLine
{
    public readonly string Message;

    public readonly object[] Params;

    public static implicit operator LogLine(string message)
    {
        return new LogLine(message ?? string.Empty);
    }

    public LogLine(string message, params object[] @params)
    {
        Message = message;
        Params = @params;
    }
}

Проверено с:

  • FakeItEasy v6.0.1
  • MSTest.TestAdapter v2.1.1
  • MSTest.TestFramework v2.1.1

1 Ответ

2 голосов
/ 14 апреля 2020

FakeItEasy не может сказать, как был создан объект, переданный методу. Второму вызову _logger.Error передается экземпляр LogLine, поэтому я думаю, что вы хотите проверить сам этот объект. В частности, вы можете посмотреть на свойство Message.

Попробуйте

A.CallTo(() => fakeLogger.Error(
        A<LogLine>.That.Matches(ll => ll.Message.Contains("LogLine")))
    ).MustHaveHappenedOnceExactly();
...