问题
How can I mole the DataContext that I'm using in a class to write messages to a table. I'd like to assert that the table LINQ is writing to has the expected count of messages. Here's what i have so far.
var context = new MJustTestingDataContext();
MyMessagewriter writer = new MyMessageWriter(context);
var messageList = new List<MIncmoingMessage>();
MTable<MIncomingMessage> messageTable = new MTable<MIncomingMessage>();
messageTable.Bind(messagesLinqList.AsQueryable());
If I use this code with xUnit in my class under test I'll get this exception
Microsoft.Moles.Framework.Moles.MoleNotImplementedException: DataContext.Dispose() was not moled.
What am I missing here and how to implement DataContext.Dispose() on the mole? I'm using moles standalone without Pex.
回答1:
When you create a new Mole the default behavior for its methods and properties is to throw a MoleNotImplementedException
whenever they are called.
To implement the mole you can do
I reread the question and you probably are having a problem since context.Dispose = () => {};
which means that nothing happens when the Dispose
method gets called on the moled instance.Dispose
is defined in a base class. To mole base method you need to do the following:
var context = new MJustTestingDataContext();
var baseContext = new MDataContext(context);
baseContext.Dispose = () => {};
You'll need to implement every property/method that gets called by the code under test or you can set the default behavior for the mole instance globally using the method BehaveAsDefaultValue
. This way every method in the mole will do nothing and return the default value for it's return type if one exists instead of throwing a MoleNotImplementedException
. However if you require this behavior it's better to use a stub than a mole.
回答2:
I'm having trouble understanding what your test is doing. I had to do something similar yesterday, so I'll share my experience. First, it's important to understand that you don't need to use all the MoleTypes to test your code -- you just need to use Moles to redirect certain parts of your code to lambda expressions. Given a method that does this:
- get a list of users to modify from the database
- modify every user in the set
- send the new set back to the database
I'd like to redirect 1 and 3 to not use the database. For instance, I can redirect the call to SubmitChanges
(3) via this code:
bool hitSubmitChanges = false;
int changeCount = 0;
IList<object> updates = null;
// more code here...
// redirect DataContext.SubmitChanges() to a lambda to catch updates
MDataContext.AllInstances.SubmitChanges = (c) =>
{
changeCount = c.GetChangeSet().Updates.Count;
updates = c.GetChangeSet().Updates;
hitSubmitChanges = true;
};
That (and the call to get the users) would be the only Moletypes I'd use in the test. The rest of it would be normal. Then I can use assertions to check the values of changeCount, updates and hitSubmitChanges.
来源:https://stackoverflow.com/questions/3685589/moling-datacontext-with-ms-moles