I'm having problems to test a method that has a ref parameter. I'm not the library/code owner, so I can't change it, so please do not suggest that I remove the ref parameter.
I'm using this website as reference: http://ayende.com/wiki/Rhino%20Mocks%203.5.ashx#OutandRefarguments
Here is the test:
[Test]
public void TestBuildSimpleProfile()
{
// arrange
var barMock = MockRepository.GenerateStrictMock<ICommandBar>();
var controlBuilder = new ControlBuilder(barMock);
var user = new Usuario();
user.PRF_PERFIS = new Perfis();
var perfil = new Perfil();
perfil.FNC_FUNCIONALIDADES = new Funcionalidades();
var func1 = new Funcionalidade();
func1.FNC_NU_ID = 1;
func1.FNC_FL_ATIVO = true;
func1.FNC_NO_CHAVE = "Associar Registros";
func1.FNC_DE_FUNCIONALIDADE = "{0653aeac-c5ef-46fa-9e99-408719296ed3}";
perfil.FNC_FUNCIONALIDADES.Add(func1);
user.PRF_PERFIS.Add(perfil);
var funcs = new List<IFunctionality>();
funcs.Add(new FunctionalityAttribute(1,"Associar Registros", "{0653aeac-c5ef-46fa-9e99-408719296ed3}", "SGIGT", true,"admin,editor"));
var uid = new UIDClass() { Value = "{0653aeac-c5ef-46fa-9e99-408719296ed3}" };
var arg = Arg<object>.Ref(Is.Anything(), 0).Dummy;
// act
controlBuilder.Build(user, funcs);
// assert
barMock.AssertWasCalled(x => x.Add(uid, ref arg), y => y.IgnoreArguments());
}
Here is the error I'm finding:
Rhino.Mocks.Exceptions.ExpectationViolationException : ICommandBar.Add(ESRI.ArcGIS.esriSystem.UIDClass, 0); Expected #0, Actual #1.
I've already tried a number of ways, but it simply does not work. The build method implementation is below. This just receives a list of functions to build and an user, which has associated functions. If he has a function, it should be build, using the add method.
public void Build(Usuario u, List<IFunctionality> funcsToBuild)
{
if (u == null)
throw new ArgumentNullException("u");
if (funcsToBuild == null)
throw new ArgumentNullException("funcsToBuild");
if (u.PRF_PERFIS == null || u.PRF_PERFIS.Count <= 0)
return;
var functionList = (from funcs in funcsToBuild
select funcs.FunctionDescription).ToList();
var userFuncs = (from profile in u.PRF_PERFIS
from functionality in profile.FNC_FUNCIONALIDADES
where functionality.FNC_FL_ATIVO.HasValue && functionality.FNC_FL_ATIVO.Value && functionList.Contains(functionality.FNC_DE_FUNCIONALIDADE)
select new FunctionalityAttribute((int)functionality.FNC_NU_ID.Value,functionality.FNC_NO_CHAVE, functionality.FNC_DE_FUNCIONALIDADE, "SGIGT", true, "")).Cast<IFunctionality>().OrderBy(x => x.FunctionId).ToList();
for (int index = 0; index < userFuncs.Count; index++)
{
IFunctionality t = userFuncs[index];
object i = index;
var functionality = t;
var uid = new UIDClass() {Value = functionality.FunctionDescription};
var ci = _commandBar.Add(uid, ref i);
}
}
Any chance someone can help me?
You can use Arg<> to match on expectations for Out/Ref parameters. If you don't care about the actual value, you could use something like the following:
If you do care about matching input/output values, then you could use this instead:
I think your test is most likely failing because uid is not the same instance as the one passed into ICommandBar, rather than a specific issue with the Ref parameter. You can solve this by using Equals as shown above, rather than using reference equality.
If all else fails and UIDClass doesn't implement equals correctly, you can always use a matching predicate:
Well I think the issue may have to do with MockRepository.GenerateStrictMock() versus MockRepository.GenerateMock(); And then adding the Repeat.Times(1) on the IMethodoptions. You should be able to ensure that Add gets called based on the number of items in the list of funcs with this code appropriately.