c#中类参数的模拟类

问题描述 投票:2回答:2

我有一个班级客户。它有如下方法,

public class Client
{
   public Client(string portNum);
   public void Init();
   public void SendMsg(byte[] msg);
   public byte[] Receive();
}

我正在使用课堂进行交流。客户端是第三方库中的类,因此我无法编辑类Client。

我需要为客户编写Mock类来为我的班级做单元测试。我正在使用Visual studio单元测试。 .Net 4.5。对于Mock,我正在使用Moq.dll。我尝试如下,

        [TestMethod]
        public void TestSend()
        {
            var mockClient = new Mock<Client>();
            mockClient.Setup(x => x.SendMsg(It.IsAny<byte[]>())).Callback<byte[]>((m) => Send(m));
            Assert.IsTrue(isInit);
        }

    private void Send(byte[] msg)
    {

    }

它如下所示抛出异常,

Moq.dll中出现“System.NotSupportedException”类型的异常,但未在用户代码中处理

附加信息:非虚拟(在VB中可覆盖)成员的无效设置:x => x.SendMsg(It.IsAny())

任何人都可以说出错误,我已经做到了。以及如何纠正它。提前致谢。

c# unit-testing mocking
2个回答
6
投票

评论说明了一切 - 你不能以这种方式嘲笑。

你可以做什么:

1. setup a (lean) interface with all you need:

public interface IClient
{
   public void Init();
   public void SendMsg(byte[] msg);
   public byte[] Receive();
}

2. make a facade around client to implement it:

public class MyClient : IClient
{
   private Client _client;

   /* implement everything in the obvious way by using the private field */
}

3. use the interface instead of Client in your code

抱歉没看到这个

只需插入IClient而不是Client并将其注入您的构造函数中。

4. Mock the interface

[TestMethod]
public void TestSend()
{
   var mockClient = new Mock<IClient>();
   mockClient.Setup(x => x.SendMsg(It.IsAny<byte[]>())).Callback<byte[]>((m) => Send(m));

   // ....
   Assert.IsTrue(isInit);
}

1
投票

稍微调整了Carsten的答案,这已经非常彻底了。

当你创建自己的类时,扩展Client类并实现接口,如下所示:(假设“Client”类没有被密封,在这种情况下这不起作用)

public class DerivedClient : Client, IClient
{
    public DerivedClient(string portNum)
        : base(portNum) {}
}

这样,您不必复制基本Client类中的所有方法(在这种情况下只有3个,但在另一个场景中可能更多),因为它实际上只是对基础Client中所有内容的传递类。

理想情况下,如果您正在使用Unity等DI服务,则会在请求DerivedClient实例时将其配置为实例化IClient

© www.soinside.com 2019 - 2024. All rights reserved.