预期至少对模拟调用一次,但在尝试模拟和验证简单测试时从未执行过

Expected invocation on the mock at least once, but was never performed when trying to mock and verify a simple test

我正在尝试执行一个简单的模拟并验证

[TestClass]
    public class PublisherTests
    {
        Mock<IPublisher> myPublisherMock;
        Publisher publisher;

        [TestInitialize]
        public void Initialize()
        {


            myPublisherMock = new Mock<IPublisher>();

            publisher = new Publisher(myPublisherMock.Object);

        }
        [TestMethod]
        public void ShouldReturnNegativeWhenMsgIsInvalid1()
        {
            string msg = "abc";
            long result = -1;
            myPublisherMock.Setup(m => m.GetMessageCount(msg)).Returns(result).Verifiable();
            publisher.GetMessageCount(msg);
            myPublisherMock.Verify(m => m.GetMessageCount(msg));

        }

    }

但它总是抛出异常

Moq.MockException: ' Expected invocation on the mock at least once, but was never performed: m => m.GetQueueMessageCount1(It.IsAny())

Performed invocations:

   Mock<IPublisher:1> (m):
   No invocations performed.

实际方法

public class Publisher : IPublisher
{   
 private IPublisher MyPublisher { get; set; }
    public Publisher(IPublisher publisher)
    {
        MyPublisher = publisher;
    }

    public long GetMessageCount(string msg)
   {
    long result = 0;

    try
    {
        if (msg == "abc")
            throw new Exception();

        return result;
    }
    catch (Exception ex)
    {
        var p = ex.Message;
        return result = -1;
    }


   }
}

无法确定我哪里出错了。

基于所示示例并假设这是对装饰器模式的测试

例如

public interface IPublisher {
    long GetMessageCount(string msg);
}

public class Publisher : IPublisher {
    private readonly IPublisher publisher;

    public Publisher(IPublisher publisher) {
        this.publisher = publisher;
    }

    public long GetMessageCount(string msg) {
        long result = 0;
        try {
            if (msg == "abc")
                throw new Exception();

            result = publisher.GetMessageCount(msg);
            return result;
        } catch (Exception ex) {
            var p = ex.Message;
            return result = -1;
        }
    }
}

如果测试想要测试抛出异常时的预期行为,则无需在 mock 上设置成员,因为它预计不会被调用。

但是您可以验证它从未被调用过。

例如

[TestMethod]
public void ShouldReturnNegativeWhenMsgIsAbc() {
    //Arrange
    var myPublisherMock = new Mock<IPublisher>();

    long expected = -1;

    var subject = new Publisher(myPublisherMock.Object);

    //Act
    var actual = subject.GetMessageCount("abc");

    //Assert
    actual.Should().Be(expected); //FluentAssertion
    myPublisherMock.Verify(_ => _.GetMessageCount(It.IsAny<string>()), Times.Never);
}