Как установить элементы массива с Moq? - PullRequest
0 голосов
/ 11 октября 2018

Я использую Moq для моделирования представления и модели для тестирования докладчика.

Я хотел бы использовать моделирование для подтверждения того, что члены массива моей модели и представления действительно установлены в методах ResetStatuses и UpdateTxtStatuses.

Однако выполнение теста приводит к ошибке при моем вызове ResetStatuses с сообщением об ошибке:

Result StackTrace:  
at DSimGui.SocketStatusIGSSPresenter.ResetStatuses() in C:\dev\dir\DG\DSimGui\SocketStatusIGSSPresenter.cs:line 89
   at DSimGuiTest.SocketStatusIGSSTest.VerifyResetStatuses() in C:\dev\dir\DG\DSimGuiTest\SocketStatusIGSSTest.cs:line 82
Result Message: 
Test method DSimGuiTest.SocketStatusIGSSTest.VerifyResetStatuses threw exception: 
System.IndexOutOfRangeException: Index was outside the bounds of the array.

Я подумал, что для этого необходимо использовать SetupSet для подготовки участников к настройке, но использование SetupSet для txtClientStatuses привело к другой ошибке:

Result StackTrace:  
at DSimGuiTest.SocketStatusIGSSTest.<>c__DisplayClass1_0.<VerifyResetStatuses>b__3(SocketStatusIGSSIModel a) in C:\dev\dir\DG\DSimGuiTest\SocketStatusIGSSTest.cs:line 88
   at Moq.Mock.SetupSetImpl[T,TCall](Mock`1 mock, Action`1 setterExpression, Func`5 callFactory) in C:\projects\moq4\Source\Mock.cs:line 666
   at Moq.Mock.SetupSetPexProtected[T](Mock`1 mock, Action`1 setterExpression, Condition condition) in C:\projects\moq4\Source\Mock.cs:line 626
   at Moq.PexProtector.Invoke[T1,T2,T3,TResult](Func`4 function, T1 arg1, T2 arg2, T3 arg3) in C:\projects\moq4\Source\PexProtector.cs:line 75
   at DSimGuiTest.SocketStatusIGSSTest.VerifyResetStatuses() in C:\dev\dir\DG\DSimGuiTest\SocketStatusIGSSTest.cs:line 88
Result Message: 
Test method DSimGuiTest.SocketStatusIGSSTest.VerifyResetStatuses threw exception: 
System.IndexOutOfRangeException: Index was outside the bounds of the array.

Как правильно вызвать SetupSet для индексов массива?Предполагая, что это позволит докладчику устанавливать элементы массива без ошибок.

Мой код указан ниже:

Presenter

public class SocketStatusIGSSPresenter
{
    private readonly SocketStatusIGSSIView view;
    private readonly SocketStatusIGSSIModel model;
    private readonly EventHub eventHub;

    public SocketStatusIGSSPresenter(
        SocketStatusIGSSIView view,
        SocketStatusIGSSIModel model)
    {
        this.view = view;
        view.Presenter = this;

        this.model = model;
        Initialize();
    }

    private void Initialize()
    {
        model.txtClientStatuses = new string[4];
        model.txtServerStatuses = new string[4];
        model.txtIGSSCmd = "";
    }

    public void ResetStatuses()
    {
        for (int i = 1; i <= 3; i++)
        {
            model.txtClientStatuses[i] = "0";
            model.txtServerStatuses[i] = "0";
        }
        UpdateTxtStatuses();
    }

    public void UpdateTxtStatuses()
    {
        for (int i = 1; i <= 3; i++)
        {
            view.txtClientStatuses[i].Text = model.txtClientStatuses[i];
            view.txtServerStatuses[i].Text = model.txtServerStatuses[i];
        }
    }
}

Метод испытания

[TestMethod]
public void VerifyResetStatuses()
{
    var model = new Mock<SocketStatusIGSSIModel>();
    model.SetupSet(a => a.txtClientStatuses = It.IsAny<string[]>());
    model.SetupSet(a => a.txtServerStatuses = It.IsAny<string[]>());
    model.SetupSet(a => a.txtIGSSCmd = It.IsAny<string>());

    var view = new Mock<SocketStatusIGSSIView>();
    var eventHub = new EventHub();
    var presenter = new SocketStatusIGSSPresenter(view.Object, model.Object, eventHub);

    // Results in error!
    //for (int i = 0; i < 4; i++)
    //{
    //  model.SetupSet(a => a.txtClientStatuses[i] = It.IsAny<string>());
    //}

    // Results in error!
    //presenter.ResetStatuses();

    // This will be used to verify that txtClientStasuses array elements are set
    //model.VerifySet(a => a.txtClientStatuses[It.IsAny<int>()] = It.IsAny<string>(), Times.Exactly(3));
}

Интерфейс модели

public interface SocketStatusIGSSIModel
{
    string[] txtClientStatuses { get; set; }

    string[] txtServerStatuses { get; set; }

    string txtIGSSCmd { get; set; }

    string TxtDataValue { get; set; }

    short TxtSrcSeqCnt { get; set; }
}

Просмотр интерфейса

public interface SocketStatusIGSSIView
{
    SocketStatusIGSSPresenter Presenter { set; }

    TextBox[] txtClientStatuses { get; set; }

    TextBox[] txtServerStatuses { get; set; }

    string TxtIGSSCmd { get; set; }

    string TxtDataValue { get; set; }

    string TxtSrcSeqCntValue { get; set; }

    void Show();

    void Hide();
}

1 Ответ

0 голосов
/ 11 октября 2018

Не издевайтесь над массивом.Создайте в тесте обычный массив.Код установит записи этого массива.

var mockTxtClientStatuses = new string[4]; // or maybe new string[] { "foo", "bar", "x", "y", }
model.Setup(x => x.txtClientStatuses).Returns(mockTxtClientStatuses);
// ...
presenter.ResetStatuses();
// verify that mockTxtClientStatuses has correct entries now

Если вас это не устраивает, в качестве альтернативы используйте интерфейс (например, IList<string>), который реализует string[].То есть:

public interface SocketStatusIGSSIModel
{
  IList<string> txtClientStatuses { get; set; }
// ...

Moq может макетировать интерфейс, включая его индексаторы.Moq не может издеваться над конкретным типом массива, таким как string[].

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...