【发布时间】:2015-10-14 05:16:10
【问题描述】:
我收到了一些需要添加一些单元测试的代码。
有问题的类是一个 Socket 服务器,它异步侦听任何尝试连接的客户端,并将它们添加到套接字列表中以侦听数据。显然还有更多内容,但这应该足够开始了。
课程大纲如下:
public class MyServer
{
private Socket _Server;
private List<MyClient> _clients;
public int ClientCount
{
_clients.Count;
}
public void StartListening()
{
_Server = new Socket(...)
... // Configure the socket
_Server.BeginAccept(new AsyncCallback(AddPotentialClient), null);
}
private void AddPotentialClient(IAsyncResult result)
{
var clientSocket = (Socket)result.AsyncState;
var newClient = new MyClient(clientSocket);
_clients.Add(newClient);
}
}
首先,我想检查当客户成功注册时,注册客户的数量 (ClientCount) 是否增加了 1。就目前而言,代码并没有使单元测试变得非常容易,所以我首先引入了一个 ISocket 接口和 SocketAdapter 包装器来帮助模拟。然后我修改了 StartListening() 方法,以便可以注入 Mock,如下所示:
public void StartListening(ISocket server)
{
_Server = server;
_Server.BeginAccept(new AsyncCallback(AddPotentialClient), null);
}
这就是我卡住的地方。我可以启动一个模拟,我可以将模拟带入课堂,我知道我想检查什么,但是我应该如何配置模拟来刺激我正在检查的增量。如果可能的话,我不想假设有关 MyServer 类的内部状态的任何事情,如果它有助于简化测试,我很乐意重构现有代码。
到目前为止,我使用 moq 进行了以下测试:
[Test]
public void ClientConnecting_Increments_ClientCountBy1()
{
var testServer = new MyServer();
var mockASyncResult = new Mock<IAsyncResult>();
var mockSocket = new Mock<ISocket>();
// mockASyncResult needs to be configured so that it can be cast to an <ISocket>
// Forwards configured mockASyncResult to AddPotentialClient() method
mockSocket.Setup(x => x.BeginAccept(It.IsAny<AsyncCallack>(), null))
.Returns(mockASyncResult.Object);
_manager.StartListening(mockSocket.Object);
Assert.That(_manager.ClientCount, Is.EqualTo(ONE_CLIENT));
}
【问题讨论】:
标签: c# unit-testing mocking moq