【发布时间】:2015-04-27 15:59:21
【问题描述】:
我目前正在构建一个组件,用于向不同的 JMS 代理(例如 ActiveMQ、TibcoEMS)发送和接收消息。 显然,我想构建单元测试来验证这个组件的功能。我想测试的一件事是发送消息的方法。
public void Send( IJmsMessage jmsMessageToSend ) {
TIBCO.EMS.Connection connection = TempPermLayer.GetConnection();
connection.Start();
Session session = TempPermLayer.GetSession(connection);
MessageProducer producer = TempPermLayer.GetMessageProducer(session);
try {
IMessageFactory<Message> messageFactory = new TibcoEmsMessageFactory(session, producer);
Message message = messageFactory.ProduceMessageUsing(jmsMessageToSend);
producer.Send(message);
}
finally {
TempPermLayer.CleanUp();
}
}
层类用于对方法的实际行为方式进行细粒度控制,因此是必要的。最后上面的方法会归结为这样的:
public void Send( IJmsMessage jmsMessageToSend ) {
ConnectionFactory connectionFactory = new ConnectionFactory(Host);
Connection connection = connectionFactory.CreateConnection();
connection.Start();
Session session = connection.CreateSession(false, SessionMode.ClientAcknowledge);
Destination dest = session.CreateQueue("myQueue");
MessageProducer producer = session.CreateProducer(dest);
IMessageFactory<Message> messageFactory = new TibcoEmsMessageFactory(session, producer);
Message message = messageFactory.ProduceMessageUsing(jmsMessageToSend);
producer.Send(message);
}
IJmsMessage 和 TibcoEmsMessageFactory 基本上是代理特定实现的包装器(例如 TIBCO.EMS.Message)。
测试第一个提供的方法实际上并不是测试我不需要测试的功能,例如 Tibco EMS 客户端实现如何创建连接。涉及到相当多的附加功能 - 与第二种方法不同,我不会实际测试;)
我看到了两种测试这种方法的方法:
- 模拟所有依赖项,直至核心。这是我目前正在采用的方法,事实证明它非常耗费人力 - 这是迄今为止我能看到的唯一真正的缺点。
- 在某处托管实际的 JMS 代理,可能在本地。这可能就像在单元测试开始时执行的 jar 文件一样简单。我相信,这将使单元测试最初更容易编写。我已经看到在一些 Rest-clients 中使用了这种方法(例如,只需启动 Jetty)。它消除了模拟所有依赖项的需要,但从长远来看,它可能会使单元测试过程更难维护——尤其是在涉及构建服务器时。
实际问题:
还有其他我忘记的方法或可能性吗?如果不是,在我的情况下,您认为上述哪种方法更可取?
【问题讨论】:
标签: c# unit-testing activemq moq tibco-ems