Как смоделировать метод с несколькими параметрами Ref - PullRequest
3 голосов
/ 01 декабря 2011

У меня есть вызов этого метода

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

вend Я ожидаю, что у меня будет «test» в GroupAdmin и GroupTrans, но я получаю сообщение об ошибке:

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

Чего мне не хватает?Может кто-нибудь помочь мне высмеять это?

Спасибо

Ответы [ 2 ]

4 голосов
/ 01 декабря 2011

После некоторой «тяжелой» работы нашли решение

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

, проблема заключалась в неправильном использовании Callback вместо Returns

0 голосов
/ 24 июля 2017

Я понимаю, что ваше решение работает, и понимаю, что это старый пост, но вот еще одна более простая версия реализации для людей из будущего:)

Метод репозитория:

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

Все готово.

...