Reputation: 871
I have this method call
SecurityController.GetUserPermissions( _
HttpContext.Current.User.Identity.Name.ToString, GroupAdmin, GroupTrans)
where GroupAdmin and GroupTrans are array of string and are ByRef parameters.
So basically what it does is, given a username fill in the array of admin rights and the array of allowed transactions.
This is legacy code that I can't change.
here's part of my test:
var moqSecurityController = new Mock<ISecurityController>();
var refParam = new string[1] {"test"};
moqSecurityController
.Setup(x => x.GetUserPermissions("Bob", ref refParam, ref refParam))
.Callback((string userName, string[] groupAdmin, string[] groupTrans) =>
{
groupAdmin[0] = "Test a";
groupTrans[0] = "Test b";
});
at the end I would expect to have "test" in both GroupAdmin and GroupTrans, but I'm getting an error:
Invalid callback. Setup on method with parameters (String,String[]&,String[]&)
cannot invoke callback with parameters (String,String[],String[])
What am I missing? Can anyone please help me mock this?
Thanks
Upvotes: 3
Views: 3217
Reputation: 1681
I get that your solution works, and understand this is an old post, but here is another simpler version of implementation for people from the future :)
Repository method:
public T Get<T>(params KeyValuePair<string, object>[] parameters) where T : class
{
// do whatever you need to do and return an object of type T;
}
UnitTest method for business class:
[TestCategory("UnitTest")]
[TestMethod]
public void UnitTest_Business_BusinessClassName_GetMethodName()
{
var mockRepositoryName = new Mock<IRepositoryName>(MockBehavior.Strict);
var businessClassName = new BusinessClassName(mockRepositoryName.Object);
var inputValue = GetInput();
var expectedResponse = new ResultModel { Id = 1 };
#region Moq
var paramsValue = new KeyValuePair<string, object>("Id", inputValue);
mockRepositoryName
.Setup(
p => p.Get<ResultModel>
(
It.Is<KeyValuePair<string, object>>(i => CheckInputs(i, paramsValue))
)
)
.Returns(expectedResponse)
;
#endregion Moq
ResultModel actual = businessClassName.Get(inputValue);
#region assertion
Assert.IsNotNull(actual, "actual");
Assert.AreEqual(inputValue, actual.Id, "Id");
#endregion
}
private static int GetInput()
{
return 1;
}
private static bool CheckInputs(KeyValuePair<string, object> source, KeyValuePair<string, object> target)
{
if (string.IsNullOrWhiteSpace(source.Value?.ToString()) ||
string.IsNullOrWhiteSpace(target.Value?.ToString()) ||
int.Parse(source.Value.ToString()) != int.Parse(target.Value.ToString()))
{
return false;
}
return true;
}
You are all set.
Upvotes: 0
Reputation: 871
After some "hard" work found the solution
var moqSecurityController = new Mock<ISecurityController>();
moqSecurityController
.Setup(x => x.GetUserPermissions(
It.IsAny<string>(), ref groupAdmin, ref groupTrans))
.Returns((string s, string[] a, string[] b) =>
{
a[0] = "TestAdmin";
b[0] = "TestTrans";
return 0;
});
the problem was the wrong use of Callback instead of Returns
Upvotes: 4