TargetParameterCountException in Moq-based unit-test
Question
We have repositories which have a "Save" method. They also throw a "Created" event whenever an entity is saved.
We have been trying to use Moq to mock out the repository as such....
var IRepository = new Mock<IRepository>();
Request request = new Request();
IRepository.Setup(a => a.Save(request)).Raises(a => a.Created += null, RequestCreatedEventArgs.Empty);
This doesn't seem to work and I always get an exception:
System.Reflection.TargetParameterCountException: Parameter count mismatch.
Any example of mocking events with Moq would be helpful.
Solution
A standard event type delegate has two arguments usually: a sender object and a subclass-of-EventArgs object. Moq expects this signature from your event, but only finds one argument and this causes the exception.
Take a look at this code with my comment, it should work:
public class Request
{
//...
}
public class RequestCreatedEventArgs : EventArgs
{
Request Request {get; set;}
}
//=======================================
//You must have sender as a first argument
//=======================================
public delegate void RequestCreatedEventHandler(object sender, RequestCreatedEventArgs e);
public interface IRepository
{
void Save(Request request);
event RequestCreatedEventHandler Created;
}
[TestMethod]
public void Test()
{
var repository = new Mock<IRepository>();
Request request = new Request();
repository.Setup(a => a.Save(request)).Raises(a => a.Created += null, new RequestCreatedEventArgs());
bool eventRaised = false;
repository.Object.Created += (sender, e) =>
{
eventRaised = true;
};
repository.Object.Save(request);
Assert.IsTrue(eventRaised);
}
OTHER TIPS
It appears that whatever is being returned from RequestCreatedEventArgs.Empty
can't be converted to a RequestCreatedEventArgs
object. I would expect the following:
class IRepository
{
public event THING Created;
}
class THING : EventArgs
{
public static THING Empty
{
get { return new THING(); }
}
}
Verify that THING is the same class in each place in your code as shown above.