如何测试作为方法参数传递的 Action 的参数?

问题描述 投票:0回答:1

我首先要声明,我对 StackOverflow、使用 NSubtitute 进行单元测试以及在 C# 中使用操作/委托很陌生 - 因此对于任何格式和/或术语的误用,我提前表示歉意。

我有以下代码:

    public class Status
    {
        public Status() { }

        public enum ReceivedStatus
        {
            NotReceived = 0,
            Received = 1
        }

        public ReceivedStatus XReceived { get; set; }

        public ReceivedStatus YReceived { get; set; }
    }

    public interface IHandler
    {
        void UpdateStatus(Action<Status> update);
    }

    public class Handler : IHandler
    {
        public void UpdateStatus(Action<Status> update)
        {
            update(_status);
            //Some additional stuff with _status would probably happen here
        }

        private Status _status = new Status();
    }

    public class Sequencer
    {
        public Sequencer(IHandler handler)
        {
            _handler = handler;
        }

        public void UpdateX()
        {
            _handler.UpdateStatus(x => x.XReceived = Status.ReceivedStatus.Received);
        }

        public void UpdateY()
        {
            _handler.UpdateStatus(x => x.YReceived = Status.ReceivedStatus.Received);
        }

        IHandler _handler;
    }

我想编写一个单元测试(使用 MSTest 和/或 NSubstitute),它可以验证是否在处理程序上调用了 UpdateStatus 方法,并在 Action 参数中传递的 Status 上设置了特定值。

我已经编写了以下单元测试代码,其中我模拟了 Handler 并将其传递给 Sequencer,在 Sequencer 上调用 UpdateX 方法,然后断言使用 Actoin 参数调用 UpdateStatus 方法:

    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {
            //Assign
            Sequencer sequencer = new Sequencer(_mockHandler);

            //Act
            sequencer.UpdateX();

            //Assert
            _mockHandler.Received().UpdateStatus(Arg.Any<Action<Status>>());
        }

        private readonly IHandler _mockHandler = Substitute.For<IHandler>();
    }

这成功断言使用 Action 参数调用了 UpdateStatus。但我真正想要的是能够断言,特别是使用 UpdateStatus 方法调用了“XReceived”设置为“Received”的 Action 参数。

任何帮助将不胜感激!

c# delegates action mstest nsubstitute
1个回答
0
投票

目前我只能通过手动检查调用来查看方法:

public void TestMethod1()
{
    //Assign
    Sequencer sequencer = new Sequencer(_mockHandler);

    //Act
    sequencer.UpdateX();

    //Assert
    _mockHandler.Received().UpdateStatus(Arg.Any<Action<Status>>());
    var action = _mockHandler.ReceivedCalls()
        .SelectMany(x => x.GetArguments())
        .OfType<Action<Status>>()
        .FirstOrDefault();
    var status = new Status() { XReceived = Status.ReceivedStatus.NotReceived };
    action(status);
    Assert.AreEqual(status.XReceived, Status.ReceivedStatus.Received);
}
© www.soinside.com 2019 - 2024. All rights reserved.