如何使用 .NET 的 MOQ 模拟 MQ 系列对象 MQQueueManager?

发布于 2024-10-05 18:33:04 字数 1641 浏览 3 评论 0原文

我正在尝试对项目的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

金橙橙 2024-10-12 18:33:04

看起来您实际上正在访问 MQQueueManager。

您需要做的是将 MQQueueManager 放在您自己的接口后面(假设该类本身尚未实现接口)并使用 Mock 来构建该接口。

因此,使用 send 方法创建一个 IMQQueueManager,并在您的实现中实际使用 MQQueueManager 进行工作,然后您的消费类应该通常通过构造函数将此接口传递给它们,以便使用 MQQueueManager。

所以你可以编写这样的实现

public interface IMQQueueManager 
{
    void Send(string message, MQManMock obj);
}

public interface ConcreteMQQueueManager : IMQQueueManager
{
    public void Send(string message, MQManMock obj)
    {
        //create a mock MQ manager
            var MQManMock = new 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); 
    }
}

,然后你将针对下面的类编写单元测试

public class myclass
{

    IMQQueueManager _manager
    public myclass(IMQQueueManager queueManager)
    {
        _manager = queueManager;
    }

    public void AddItemToQueue(string MyItem)
    {

        _manager.Send("Hello",MQManMock.Object);
    }

}

并使用 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

public interface IMQQueueManager 
{
    void Send(string message, MQManMock obj);
}

public interface ConcreteMQQueueManager : IMQQueueManager
{
    public void Send(string message, MQManMock obj)
    {
        //create a mock MQ manager
            var MQManMock = new 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); 
    }
}

then you would be writing your unit tests against the class below

public class myclass
{

    IMQQueueManager _manager
    public myclass(IMQQueueManager queueManager)
    {
        _manager = queueManager;
    }

    public void AddItemToQueue(string MyItem)
    {

        _manager.Send("Hello",MQManMock.Object);
    }

}

And using Moq to verify that send was called

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文