Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rhino.Mocks and ref parameter

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?

like image 384
George Silva Avatar asked Jan 15 '23 07:01

George Silva


1 Answers

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:

barMock.AssertWasCalled(x => 
              x.Add(Arg<UIDClass>.IsAnything(), 
              ref Arg<object>.Ref(Is.Anything(), null).Dummy);

If you do care about matching input/output values, then you could use this instead:

barMock.AssertWasCalled(x => 
              x.Add(Arg<UIDClass>.Is.Equal(uid), 
              ref Arg<object>.Ref(Is.Same(input), output).Dummy);

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:

barMock.AssertWasCalled(x => 
              x.Add(Arg<UIDClass>.Is.Matching(
                    delegate(UIDClass u) { return u.Value == uid.Value; }
              ), 
              ref Arg<object>.Ref(Is.Same(input), output).Dummy);
like image 144
TheCodeKing Avatar answered Jan 25 '23 03:01

TheCodeKing