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??
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
精彩评论