如何使用 .NET 的 MOQ 模拟 MQ 系列对象 MQQueueManager?
我正在尝试对项目的 MQ-Series 实现进行单元测试,并且需要模拟与 MQ-Series 服务器的连接以测试隔离的实现并避免从实际队列发送消息/检索消息。
这是代码:
using IBM.WMQ;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
namespace Test
{
[TestClass]
public class MQTest
{
[TestMethod]
public void SendMessage_MoqUnitTest()
{
//create a mock MQ manager
var mqManMock = new Mock<MQQueueManager>();
//test by calling the send method
MyMQhandler.MQSender mqsender = new MyMQhandler.MQSender();
//error happens when trying to access the moq object here
mqsender.Send("test message", mqManMock.Object);
}
}
}
我知道我还没有对最小起订量进行任何设置,但问题出现在任何代码实际运行之前。
问题是,当我这样做时,我遇到了异常。 来自内部异常的堆栈跟踪,消息为“发生 I/O 错误”:
at IBM.WMQ.MQChannelTable.CreateChannelEntryLists(MQChannelListEntry nameList) 在IBM.WMQ.Nmqi.ManagedNmqiMQ.CreateNameListEntryFromCCDT(字符串qMgrName,字符串ccdtFile) 在IBM.WMQ.Nmqi.ManagedNmqiMQ.CreateNameListEntryFromCCDT(字符串qMgrName) 在 IBM.WMQ.Nmqi.ManagedNmqiMQ.GetNameList(String qMgrName) 在 IBM.WMQ.Nmqi.ManagedNmqiMQ.DoConn(String qMgrName, MQConnectOptions cno, ManagedHconn manHconn, Int32& hConn, Int32& compCode, Int32& Reason) 在IBM.WMQ.Nmqi.ManagedNmqiMQ.MQCONNX(字符串pQMgrName,MQConnectOptions pConnectOpts,Phconn phconn,Int32&pCompCode,Int32&pReason) 在IBM.WMQ.MQQueueManager.Connect(字符串队列管理器名称) 在 IBM.WMQ.MQQueueManager..ctor() at Castle.Proxies.MQQueueManagerProxy..ctor(IInterceptor[] )
大多数时候我运行它,尽管我只是得到 MQManMock.Object 的“函数评估超时”。
这是否意味着我不能嘲笑 MQ?
I am trying to unit test the MQ-Series implementation of my project, and need to mock the connection to the MQ-Series server to test my implementation isolated and avoid sending messages/retrieving messages from the actual queue.
Here is the code:
using IBM.WMQ;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
namespace Test
{
[TestClass]
public class MQTest
{
[TestMethod]
public void SendMessage_MoqUnitTest()
{
//create a mock MQ manager
var mqManMock = new Mock<MQQueueManager>();
//test by calling the send method
MyMQhandler.MQSender mqsender = new MyMQhandler.MQSender();
//error happens when trying to access the moq object here
mqsender.Send("test message", mqManMock.Object);
}
}
}
I am aware that I am not doing any setup on the moq yet, but the problem appears before any code is actually run against it.
The problem is that when I do this I get an exception.
Stack trace from the inner exception with message "I/O error occurred":
at IBM.WMQ.MQChannelTable.CreateChannelEntryLists(MQChannelListEntry nameList)
at IBM.WMQ.Nmqi.ManagedNmqiMQ.CreateNameListEntryFromCCDT(String qMgrName, String ccdtFile)
at IBM.WMQ.Nmqi.ManagedNmqiMQ.CreateNameListEntryFromCCDT(String qMgrName)
at IBM.WMQ.Nmqi.ManagedNmqiMQ.GetNameList(String qMgrName)
at IBM.WMQ.Nmqi.ManagedNmqiMQ.DoConn(String qMgrName, MQConnectOptions cno, ManagedHconn manHconn, Int32& hConn, Int32& compCode, Int32& reason)
at IBM.WMQ.Nmqi.ManagedNmqiMQ.MQCONNX(String pQMgrName, MQConnectOptions pConnectOpts, Phconn phconn, Int32& pCompCode, Int32& pReason)
at IBM.WMQ.MQQueueManager.Connect(String queueManagerName)
at IBM.WMQ.MQQueueManager..ctor()
at Castle.Proxies.MQQueueManagerProxy..ctor(IInterceptor[] )
Most of the time I run it though I just get "Function evaluation timed out" og the MQManMock.Object.
Does this mean that I can't mock the MQ??
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
看起来您实际上正在访问 MQQueueManager。
您需要做的是将 MQQueueManager 放在您自己的接口后面(假设该类本身尚未实现接口)并使用 Mock 来构建该接口。
因此,使用 send 方法创建一个 IMQQueueManager,并在您的实现中实际使用 MQQueueManager 进行工作,然后您的消费类应该通常通过构造函数将此接口传递给它们,以便使用 MQQueueManager。
所以你可以编写这样的实现
,然后你将针对下面的类编写单元测试
并使用 Moq 来验证发送是否被调用
Looks like you are actually hitting the MQQueueManager.
What you need to do it put the MQQueueManager behind your own interface (assuming the class itself doesn't already implement an interface) and use Mock to build that interface.
so create an IMQQueueManager with a send method and in your implementation actually do the work with MQQueueManager your consuming classes should then have this interface passed into them usually by through the constructor in order to use the MQQueueManager.
so you could write an implementation like this
then you would be writing your unit tests against the class below
And using Moq to verify that send was called