【问题标题】:How to mock a method with multiple Ref params如何模拟具有多个 Ref 参数的方法
【发布时间】:2011-12-01 08:41:29
【问题描述】:

我有这个方法调用

SecurityController.GetUserPermissions( _
     HttpContext.Current.User.Identity.Name.ToString, GroupAdmin, GroupTrans)

其中 GroupAdmin 和 GroupTrans 是字符串数组,是 ByRef 参数。

所以基本上它的作用是,给定一个用户名,填写管理员权限数组和允许的事务数组。

这是我无法更改的遗留代码。

这是我的部分测试:

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

最后,我希望在 GroupAdmin 和 GroupTrans 中都有“测试”,但我得到了 一个错误:

Invalid callback. Setup on method with parameters (String,String[]&,String[]&)
cannot invoke callback with parameters (String,String[],String[])

我错过了什么?谁能帮我模拟一下?

谢谢

【问题讨论】:

    标签: unit-testing mocking nunit moq pass-by-reference


    【解决方案1】:

    经过一番“艰苦”的工作找到了解决办法

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

    问题是错误地使用了回调而不是返回

    【讨论】:

      【解决方案2】:

      我知道您的解决方案有效,并且知道这是一篇旧帖子,但这是未来人们的另一个更简单的实施版本:)

      存储库方法:

          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方法:

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

      一切就绪。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-05-05
        • 2017-03-01
        • 1970-01-01
        • 2013-03-10
        • 1970-01-01
        • 2019-03-31
        • 2012-06-12
        相关资源
        最近更新 更多