我正在做的是以计算程序的形式使用TCP客户端到服务器。"client“输入一个数学命令和两个数字,服务器为他执行计算并返回一个结果(exp )。加5 5;结果是10)。要做到这一点,服务器需要启动并运行,然后客户端应该尝试连接。服务器和客户端是两个不同的控制台应用程序。
现在,为了测试程序,我将与客户端相关的代码移动到一个测试项目中,并从它的正常项目中运行服务器。这是可行的,测试通过了:
[TestClass]
public class UnitTest1
{
static TcpClient connectionSocket = new TcpClient("localhost", 5678);
static Stream ns = connectionSocket.GetStream();
static StreamReader sr = new StreamReader(ns);
static StreamWriter sw = new StreamWriter(ns);
[TestMethod]
public void TestMethodAdd()
{
int response = GetResponce("Add 5 5");
Assert.AreEqual(response, 10);
}
[TestMethod]
public void TestMethodSubstract()
{
int response = GetResponce("Substract 5 5");
Assert.AreEqual(response, 0);
}
[TestMethod]
public void TestMethodMultiply()
{
int response = GetResponce("Multiply 5 5");
Assert.AreEqual(response, 25);
}
[TestMethod]
public void TestMethodDivide()
{
int response = GetResponce("Divide 5 5");
Assert.AreEqual(response, 1);
}
[TestMethod]
public void TestMethodPercent()
{
int response = GetResponce("Percent 100 5");
Assert.AreEqual(response, 5);
KillConnection();
}
private static void KillConnection()
{
connectionSocket.Close();
ns.Close();
}
private static int GetResponce(string request)
{
sw.AutoFlush = true;
sw.WriteLine(request);
string message = sr.ReadLine();
return Convert.ToInt32(message);
}
}我应该执行的下一步是使单元测试自给自足,将其编码为通过ClassInitialize自己创建、启动和停止服务器。
我该怎么做?
这不工作,我的尝试是移动测试类中的服务器代码,然后运行使用ClassInitialize启动它的方法。
class TcpChatServerA
{
public void StartServer()
{
TcpListener listener = new TcpListener(5678);
//Console.WriteLine("Server is started.");
listener.Start();
TcpClient connectionSocket = listener.AcceptTcpClient();
ChatService service = new ChatService(connectionSocket);
service.ServiceHandler();
listener.Stop();
}
}
class ChatService
{
private TcpClient connectionSocket;
public ChatService(TcpClient connectonSocketEntry)
{
connectionSocket = connectonSocketEntry;
}
public void ServiceHandler()
{
//Console.WriteLine("Server is activated");
Stream ns = connectionSocket.GetStream();
StreamReader sr = new StreamReader(ns);
StreamWriter sw = new StreamWriter(ns);
sw.AutoFlush = true;
string message = sr.ReadLine();
char[] deliminerChars = { ' ', ',', '.', '/', ':', ';' };
string[] equationMembers = new string[5];
int result = 0;
while (message != null)
{
equationMembers = message.Split(deliminerChars);
switch (equationMembers[0])
{
case "Add":
message = Convert.ToString(Convert.ToInt32(equationMembers[1]) + Convert.ToInt32(equationMembers[2]));
break;
case "Substract":
message = Convert.ToString(Convert.ToInt32(equationMembers[1]) - Convert.ToInt32(equationMembers[2]));
break;
case "Multiply":
message = Convert.ToString(Convert.ToInt32(equationMembers[1]) * Convert.ToInt32(equationMembers[2]));
break;
case "Divide":
if (equationMembers[1] == "0")
{
message = "You attempt to divide by zero please try again";
}
else if (equationMembers[2] == "0")
{
message = "You attempt to divide by zero please try again";
}
else
{
message = Convert.ToString(Convert.ToDecimal(equationMembers[1]) / Convert.ToDecimal(equationMembers[2]));
;
}
break;
case "Percent":
message = Convert.ToString(((Convert.ToDecimal(equationMembers[2])) / 100) * Convert.ToDecimal(equationMembers[1]));
break;
default:
Console.WriteLine("You did not enter a valid equation command. Valid commands are " +
"'Add', 'Substract', 'Multiply', 'Divide', Percent (y% (from) x)");
break;
}
//Console.WriteLine("Calculating...");
sw.WriteLine(message);
message = sr.ReadLine();
}
ns.Close();
connectionSocket.Close();
}
}并启动服务器:
[TestClass]
public class UnitTest1
{
[ClassInitialize]
static void Main(string[] args)
{
TcpChatServerA server = new TcpChatServerA();
server.StartServer();
}
//the rest is the test class as seen in the first code block
//static TcpClient connectionSocket = new TcpClient("localhost", 5678);
//static Stream ns = connectionSocket.GetStream();
//static StreamReader sr = new StreamReader(ns);
//static StreamWriter sw = new StreamWriter(ns);
//[TestMethod]
//public void TestMethodAdd()
//{
//int response = GetResponce("Add 5 5");
//Assert.AreEqual(response, 10);
//}
//...因此,整个守则将是:
using System;
using System.IO;
using System.Net.Sockets;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace MathTCPServerTest
{
class TcpChatServerA
{
public void StartServer()
{
TcpListener listener = new TcpListener(5678);
//Console.WriteLine("Server is started.");
listener.Start();
TcpClient connectionSocket = listener.AcceptTcpClient();
ChatService service = new ChatService(connectionSocket);
service.ServiceHandler();
listener.Stop();
}
}
class ChatService
{
private TcpClient connectionSocket;
public ChatService(TcpClient connectonSocketEntry)
{
connectionSocket = connectonSocketEntry;
}
public void ServiceHandler()
{
//Console.WriteLine("Server is activated");
Stream ns = connectionSocket.GetStream();
StreamReader sr = new StreamReader(ns);
StreamWriter sw = new StreamWriter(ns);
sw.AutoFlush = true;
string message = sr.ReadLine();
char[] deliminerChars = { ' ', ',', '.', '/', ':', ';' };
string[] equationMembers = new string[5];
int result = 0;
while (message != null)
{
equationMembers = message.Split(deliminerChars);
switch (equationMembers[0])
{
case "Add":
message = Convert.ToString(Convert.ToInt32(equationMembers[1]) + Convert.ToInt32(equationMembers[2]));
break;
case "Substract":
message = Convert.ToString(Convert.ToInt32(equationMembers[1]) - Convert.ToInt32(equationMembers[2]));
break;
case "Multiply":
message = Convert.ToString(Convert.ToInt32(equationMembers[1]) * Convert.ToInt32(equationMembers[2]));
break;
case "Divide":
if (equationMembers[1] == "0")
{
message = "You attempt to divide by zero please try again";
}
else if (equationMembers[2] == "0")
{
message = "You attempt to divide by zero please try again";
}
else
{
message = Convert.ToString(Convert.ToDecimal(equationMembers[1]) / Convert.ToDecimal(equationMembers[2]));
;
}
break;
case "Percent":
message = Convert.ToString(((Convert.ToDecimal(equationMembers[2])) / 100) * Convert.ToDecimal(equationMembers[1]));
break;
default:
Console.WriteLine("You did not enter a valid equation command. Valid commands are " +
"'Add', 'Substract', 'Multiply', 'Divide', Percent (y% (from) x)");
break;
}
//Console.WriteLine("Calculating...");
sw.WriteLine(message);
message = sr.ReadLine();
}
ns.Close();
connectionSocket.Close();
}
}
[TestClass]
public class UnitTest1
{
[ClassInitialize]
static void Main(string[] args)
{
TcpChatServerA server = new TcpChatServerA();
server.StartServer();
}
static TcpClient connectionSocket = new TcpClient("localhost", 5678);
static Stream ns = connectionSocket.GetStream();
static StreamReader sr = new StreamReader(ns);
static StreamWriter sw = new StreamWriter(ns);
[TestMethod]
public void TestMethodAdd()
{
int response = GetResponce("Add 5 5");
Assert.AreEqual(response, 10);
}
[TestMethod]
public void TestMethodSubstract()
{
int response = GetResponce("Substract 5 5");
Assert.AreEqual(response, 0);
}
[TestMethod]
public void TestMethodMultiply()
{
int response = GetResponce("Multiply 5 5");
Assert.AreEqual(response, 25);
}
[TestMethod]
public void TestMethodDivide()
{
int response = GetResponce("Divide 5 5");
Assert.AreEqual(response, 1);
}
[TestMethod]
public void TestMethodPercent()
{
int response = GetResponce("Percent 100 5");
Assert.AreEqual(response, 5);
KillConnection();
}
private static void KillConnection()
{
connectionSocket.Close();
ns.Close();
}
private static int GetResponce(string request)
{
sw.AutoFlush = true;
sw.WriteLine(request);
string message = sr.ReadLine();
return Convert.ToInt32(message);
}
}
}这给我带来了以下错误:
测试名称: TestMethodPercent
测试FullName: MathTCPServerTest.UnitTest1.TestMethodPerent
测试源:我的目录\MathTCPServerTest\UnitTest1.cs:第132行
测试结果:失败
测试持续时间: 0:00:00
结果StackTrace:
在System.Net.Sockets.TcpClient..ctor(字符串主机名,Int32端口)
at MathTCPServerTest.UnitTest1..cctor() in _My Directories_\MathTCPServerTest\UnitTest1.cs:line 97-内部异常堆栈跟踪结束
at MathTCPServerTest.UnitTest1..ctor() Result Message: Unable to create instance of class MathTCPServerTest.UnitTest1. Error: System.TypeInitializationException: The type initializer for 'MathTCPServerTest.UnitTest1' threw an exception. ---> System.Net.Sockets.SocketException: No connection could be made because the target machine actively refused it 127.0.0.1:5678.我没有正确理解ClassInitialize,是吗?
PS:对于代码改进以及如何更好地在堆栈溢出中提出问题和问题,我都愿意听取建议。
发布于 2016-01-04 22:05:25
如何为每个单元测试创建、启动和处理TCP服务器
我应该执行的下一步是使单元测试自给自足,将其编码为通过ClassInitialize自己创建、启动和停止服务器。 我该怎么做?
由于您希望开始和停止每个单元测试,并且在一个[TestClass]中包含其中的几个,所以[ClassInitialize]在这里没有用处。一种方法是将您的测试环境封装在实现IDisposable的类中,然后在单元测试中的using块中使用它。下面的代码会这样做,并回答了如何为每个单元测试创建、启动和释放TCP服务器的问题。
using System;
using System.Net.Sockets;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Net;
namespace TCPServerTest
{
class TestEnvironment : IDisposable
{
TcpListener TcpServer;
readonly public int TcpServerAddress;
public TestEnvironment(int TcpServerAddress = 5678)
{
this.TcpServerAddress = TcpServerAddress;
TcpServer = new TcpListener(IPAddress.Loopback, TcpServerAddress);
TcpServer.Start();
}
public void Dispose()
{
TcpServer.Stop();
}
}
[TestClass]
public class TestContainer
{
[TestMethod]
public void TestUsingTcpServer()
{
using (var TestEnvironment = new TestEnvironment())
{
var TcpClient = new TcpClient();
TcpClient.Connect(IPAddress.Loopback, TestEnvironment.TcpServerAddress);
Assert.IsTrue(TcpClient.Connected, "TcpClient.Connected");
}
}
}
}论ClassInitialize
我没有正确理解ClassInitialize,是吗?
考虑到你发布的代码,这似乎是可能的。这就是框架对带有[ClassInitialize]属性的方法的说明:
该方法必须是静态的、公共的,不返回值,并且应该接受TestContext类型的单个参数。
但是,即使您使用了[ClassInitialize]所需的签名,您仍然会得到相同的异常,因为您的静态字段初始化器(异常产生的地方)是在前面执行的。
发布于 2016-01-04 19:57:26
我认为您已经很好地理解了ClassInitialize,但是问题是您得到了一个Type初始化异常,这个异常通常是在类的静态字段无法初始化时抛出的。我不认为您可以使TcpClient和static -它们应该在方法的某个地方被初始化。我建议删除UnitTest1类中的所有静态字段,然后将它们移到GetResponse方法中,如下所示:
private static int GetResponce(string request)
{
TcpClient connectionSocket = new TcpClient("localhost", 5678);
Stream ns = connectionSocket.GetStream();
StreamReader sr = new StreamReader(ns);
StreamWriter sw = new StreamWriter(ns);
sw.AutoFlush = true;
sw.WriteLine(request);
string message = sr.ReadLine();
return Convert.ToInt32(message);
}(这个应该很好地工作:)
https://stackoverflow.com/questions/34597920
复制相似问题