I have a method such as:
private bool DoAction(Type typeOfConsumer, params Object[] extraParams)
I want to assert it is called, where the public equivalent is:
Mock.Arrange(() => instanceOfClass.DoAction(Arg.IsAny<Type>()).MustBeCalled();
works for the call
instanceOfClass.DoAction(typeof(SomeType)); // No params, but does this matter?
and I would expect the non-public to be
Mock.NonPublic.Arrange(instanceOfClass, "DoAction", Arg.IsAny<Type>()).MustBeCalled();
but my (NUnit) exception is System.MissingMemberException : Method 'DoAction' with the given signature was not found on type...
It works with the public equivalent and
It does not work with the non-public whether the method is made protected or private.
I want to arrange and then assert that this method was called.
5 Answers, 1 is accepted
I am sorry for the misunderstanding.
The important part here is the params parameter of the method and the way the compiler handles invocations to methods with such parameters. You can read more about it here.
The public version works, because the compiler generates code that looks like this.
Mock.Arrange(() => instanceOfClass.DoAction(Arg.IsAny<Type>(),
new
object
[] { }).MustBeCalled();
For the non public version you will need to add the array argument that the compiler adds at the place of the invocation. That is the same reason why you get the MissingMemberException, the invocation has 2 arguments - object and an array of objects.
Here is an example
Mock.NonPublic.Arrange(instanceOfClass,
"DoAction"
, ArgExpr.IsAny<Type>(), ArgExpr.IsAny<Object[]>()).MustBeCalled();
I hope that helps, let me know if you have other questions.
Regards,
Svetlozar
Telerik
Svetlozar,
Are you saying that my call to the private method DoAction() must be
DoAction(
typeof
(SomeType),
null
);
instead of
DoAction(
typeof
(SomeType));
?
Right now, asserting against
Mock.NonPublic.Arrange(instance,
"DoAction"
,
typeof
(SomeType), ArgExpr.IsNull<Object[]>()).MustBeCalled();
Gives me: Occurrence expectation failed. Expected at least 1 call. Calls so far: 0
It works if I added null as the param Object[] parameter. But I can't change all the calls in existing code for testing purposes at this time so I'm trying to find a way to do this without making such modifications.
I am sorry for the misunderstanding.
You don't need to change DoAction invocations, you need to change the Arrange methods to match the invocation, because when you don't pass an argument for the params parameter, the compiler generates code as if you've passed an empty array. Here is a complete example.
public
class
Foo
{
public
bool
PublicAction(Type type,
params
Object[] extraParams)
{
return
DoAction(type, extraParams);
}
private
bool
DoAction(Type typeOfConsumer,
params
Object[] extraParams)
{
return
false
;
}
}
And the test
[TestClass]
public
class
UnitTest1
{
[TestMethod]
public
void
TestMethod1()
{
Foo fo =
new
Foo();
Mock.NonPublic.Arrange(fo,
"DoAction"
,
typeof
(Foo), ArgExpr.IsAny<Object[]>()).MustBeCalled();
fo.PublicAction(
typeof
(Foo));
Mock.Assert(fo);
}
}
I am sorry if I am missing something here. Let me know if you have any questions.
Regards,
Telerik
Svetlozar,
After looking again more closely, your original response had the answer I was looking for.
Thank you for your help!
I am glad you've managed to resolve the issue.
Let us know if you have any other questions.
Regards,
Svetlozar
Telerik by Progress