客户端-服务器应用程序上的TDD

问题描述:

当前,我正在创建一个服务器应用程序以接收特定于协议的消息.我需要创建测试以确保正确实现了协议.这是某种集成测试吗?如果是肯定的,我可以使用单元测试工具进行集成测试吗?最后,创建此类测试的最佳方法是什么?

Currently I'm creating a server application to receive protocol-specific messages. I need to create tests to ensure that I've implemented the protocol correctly. Is this some kind of integration testing? If positive, can I make an integration testing with unit testing tools? And finally, what is the best way to create these kind of tests?

如果您知道正确的答案是什么,那么这就是我要做的事情:

If you know what the correct responses are, then here's what I'd do:

将负责处理协议逻辑的类与处理连接机制的代码分开.

Separate the class responsible for the logic of handling the protocol from the code dealing with the mechanics of the connection.

一次编写一次测试,为一组给定的输入消息指定正确的响应.

Write tests, one at a time, specifying the correct response for a given set of input messages.

实施这些行为.

例如,如果应该以"howdy"消息来响应"hello"消息,则您的测试可能如下所示:

For instance, if a "hello" message is supposed to be responded to with a "howdy" message, your test might look something like this:

Mock<IProtocolOut> outbound = new Mock<IProtocolOut>();
MyProtocolHandler handler = new MyProtocolHandler(outbound); // assuming that the handler takes the outbound receiver as a parameter.
outbound.Expect(o=>o.HowdyMessage()); // we expect to get a HowdyMessage back
handler.HelloMessage(); // 'fake' a HelloMessage into the handler
outbound.VerifyAll(); // assert that the 'howdy' message was sent.

在这种情况下,模拟程序所做的所有事情都是断言某些调用已进行.这也可以通过手动滚动类来进行验证-模拟没有什么神奇之处,它们只是使进行这种类型的验证更容易.

All the mock does in this case is assert that certain calls were made. This can be done by hand-rolling classes to do the verification as well - there's nothing magic about mocks, they just make it easier to do this type of verification.

如果您有一个支持Arrange/Act/Assert的模拟库,它将看起来像这样:

If you have a mock library that supports Arrange/Act/Assert, it'd look something more like this:

Mock<IProtocolOut> outbound = new Mock<IProtocolOut>();
MyProtocolHandler handler = new MyProtocolHandler(outbound); // assuming that the handler takes the outbound receiver as a parameter.
handler.HelloMessage(); // fake the message being sent
outbound.AssertWasCalled(o=>o.HowdyMessage());

当然,不必在消息中严格键入协议的接口.您还可以执行类似的操作:

The interfaces for the protocols don't have to be strongly typed with the messages, of course. You could also do something similar to this:

Mock<IProtocolOut> outbound = new Mock<IProtocolOut>();
MyProtocolHandler handler = new MyProtocolHandler(outbound); // assuming that the handler takes the outbound receiver as a parameter.
handler..ReceiveMessage("hello"); // fake the message being sent
outbound.AssertWasCalled(o=>o.ReceiveMessage("howdy"));

(为澄清测试范围而编辑)

(edit for clarification of test scope)

这些都不要求实际"连接.他们仅测试处理协议的 logical 方面,并假定您在逻辑协议处理和连接管理之间存在分歧.

None of these require an 'actual' connection. They test the logical aspects of handling the protocol only, and presume that you have a split between the logical protocol handling, and the connection management.