c#中类参数的模拟类

时间:2014-07-10 04:36:48

标签: c# unit-testing mocking

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

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)
    {

    }

如下所示抛出例外,

  

发生了'System.NotSupportedException'类型的异常   Moq.dll但未在用户代码中处理

     

其他信息:非虚拟设置无效(可覆盖的   VB)成员:x =&gt; x.SendMsg(It.IsAny())

任何人都可以解决这个错误,我已经完成了。以及如何纠正它。 提前谢谢。

2 个答案:

答案 0 :(得分:6)

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

你能做什么:

1。设置一个(精益)界面,您只需要:

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

2。围绕客户做一个门面来实现它:

public class MyClient : IClient
{
   private Client _client;

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

3。在您的代码

中使用界面而不是Client

抱歉在这个

上没有看到任何内容

只需插入IClient而不是Client,然后将其插入构造函数中。

4。模拟界面

[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 :(得分:1)

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

当你创建自己的类时,扩展Client类并实现接口,如下所示:(假设&#34; Client&#34;类没有被密封,在这种情况下,这将不会#39; t work)

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

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

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