2012-10-16 58 views
3

我有问题来测试具有ref参数的方法。我不是库/代码所有者,所以我不能改变它,所以请不要建议我删除ref参数。Rhino.Mocks和参考参数

我使用这个网站,作为参考: http://ayende.com/wiki/Rhino%20Mocks%203.5.ashx#OutandRefarguments

下面是测试:

[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()); 
    } 

以下是错误我发现:

Rhino.Mocks.Exceptions。 ExpectationViolationException:ICommandBar.Add(ESRI.ArcGIS.esriSystem.UIDClass,0);预期#0,实际#1。

我已经尝试了很多方法,但它根本行不通。下面是构建方法的实现。这只是收到一个要建立的功能列表和一个具有相关功能的用户。如果他有一个函数,它应该使用add方法构建。

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); 
     } 
    } 

有人可以帮助我吗?

回答

7

您可以使用Arg <>来匹配Out/Ref参数的期望值。如果你不关心实际值,你可以使用类似以下内容:

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

如果你关心匹配的输入/输出值,那么你可以使用它代替:

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

我认为你的测试很可能失败,因为uid与传入ICommandBar的实例不同,而不是Ref参数的特定问题。你可以通过使用Equals来解决这个问题,而不是使用引用等式。

如果一切都失败和UIDClass不执行等于正确,你可以随时使用匹配谓词:

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); 
+0

oooh,我还没有尝试过! :D –

+0

我是一个不错的猜测,但它也不起作用。在所有3例中同样的错误。 –

+0

那么你可能需要选择和匹配,因为它们只是使用Arg的不同方式的示例。在Ref上尝试使用Is.Anything()匹配uid上的谓词匹配。 – TheCodeKing

1
[Fact] 
    public void Test_Ref() 
    { 
     var barMock = MockRepository.GenerateMock<IDoSomething>(); 

     Composer composer = new Composer(barMock); 

     int number = 12; 

     composer.addStuff(0, number); 

     barMock.AssertWasCalled(x => x.Add(0, ref number), 
      y=>y.IgnoreArguments().Repeat.Times(1)); 
    } 

    public class Composer 
    { 
     private IDoSomething dosomething; 

     public Composer(IDoSomething doSomething) 
     { 
      this.dosomething = dosomething; 
     } 

     public void addStuff(int id, int value) 
     { 
      dosomething.Add(id, ref value); 
     } 

    } 

    public interface IDoSomething 
    { 
     void Add(int id, ref int value); 
    } 

嗯,我认为这个问题可能有MockRepository.GenerateStrictMock做的()与MockRepository.GenerateMock();然后在IMethodoptions上添加Repeat.Times(1)。您应该能够确保使用此代码适当地根据funcs列表中的项目数调用Add。

+0

我不知道我关注... –

+0

更改var barMock = MockRepository.GenerateStrictMock (); to var barMock = MockRepository.GenerateMock ();将重复添加到barMock.AssertWasCalled(x => x.Add(uid,ref arg),y => y.IgnoreArguments()。Repeat.Times(1));将时间从1更改为您希望调用.Add的次数。如果你想看到它的工作重复dosomething.Add(id,ref值)行,测试将失败。因为它会被调用两次而不是一次。 – ElvisLives