проверка списка с помощью moq - PullRequest
5 голосов
/ 19 января 2011

С учетом телефонного кода

List<Person> loginStaff = new List<Person>(); 

loginStaff.add(new Person{FirstName = "John", LastName = "Doe"});

this._iViewLoginPanel.Staff = loginStaff;

Каков синтаксис проверки того, что существует штат по имени Джон Доу и что установлен хотя бы один сотрудник? В настоящее время все примеры, которые я видел, являются довольно простыми, используя только It.IsAny или Staff = некоторый базовый тип, но ни один из них фактически не проверяет данные внутри сложных типов, таких как списки.

Мое утверждение выглядит как

this._mockViewLoginPanel.VerifySet(x=> x.Staff = It.IsAny<List<Person>>());

, который проверяет только тип, данный сеттеру, но не размер или элементы в самом списке. Я пытался сделать что-то вроде этого:

        this._mockViewLoginPanel.VerifySet(
           x =>
           {
               List<string> expectedStaffs = new List<string>{"John Doe", "Joe Blow", "A A", "Blah"};
               foreach (Person staff in x.Staff)
               {
                   if (!expectedStaffs.Contains(staff.FirstName + " " + staff.LastName))
                       return false;
               }
               return true;
           });

Но это говорит о том, что тело лямбда-оператора нельзя преобразовать в дерево выражений. Затем у меня появилась идея поместить тело оператора в функцию и запустить его, но во время выполнения я получаю:

System.ArgumentException: выражение не является вызовом установщика свойства.

Обновление: В свете первых двух ответов на использование assert я попробовал этот метод, но обнаружил, что даже после установки Staff в ненулевой список он все равно отображается в отладке как null. Так вот как выглядит полный тест

[TestMethod]
public void When_The_Presenter_Is_Created_Then_All_CP_Staff_Is_Added_To_Dropdown()
{
    this._mockViewLoginPanel = new Mock<IViewLoginPanel>();

    PresenterLoginPanel target = new PresenterLoginPanel(this._mockViewLoginPanel.Object);

    this._mockViewLoginPanel
        .VerifySet(x => x.Staff = It.IsAny<List<Person>>());

    Assert.AreEqual(5, this._mockViewLoginPanel.Object.Staff.Count);
}

И где-то внутри конструктора PresenterLoginPanel

public PresenterLoginPanel
{
    private IViewLoginPanel _iViewLoginPanel;

    public PresenterLoginPanel(IViewLoginPanel panel) 
    { 
        this._iViewLoginPanel = panel;
        SomeFunction();
    }

    SomeFunction() {
        List<Person> loginStaff = new List<Person>(); 

        loginStaff.add(new Person{FirstName = "John", LastName = "Doe"});

        this._iViewLoginPanel.Staff = loginStaff;
    }
}

Когда я отлаживаюсь до следующей строки, this._iViewLoginPanel.Staff равен нулю, что и вызывает пустое исключение в assert.

Ответы [ 3 ]

14 голосов
/ 19 января 2011

Вместо того, чтобы использовать методы макета, вы можете использовать методы NUnit, чтобы делать утверждения о содержимом объекта макета.

После того, как вы присвоили список объекту и проверили, что он задан, используйте утверждения, чтобы проверить особенности, такие как количество элементов и соответствие первого объекта тому, что вы ожидаете от него.

Assert.That(this._mockViewLoginPanel.Object.Staff.Length, Is.EqualTo(1));
Assert.That(this._mockViewLoginPanel.Object.Staff[0], Is.Not.Null);
Assert.That(this._mockViewLoginPanel.Object.Staff[0], Is.EqualTo(loginStaff[0]));

Редактировать

После дальнейшего расследования это сводится к фиктивному поведению. Свойства Staff и Person настроены неправильно.

Настройте их, измените ваше фиктивное создание на следующее:

var _mockViewLoginPanel = new Mock<IViewLoginPanel>(MockBehavior.Strict);
_mockViewLoginPanel.SetupAllProperties();

Полный список кодов демо-версии:

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

public interface IViewLoginPanel
{
    IList<Person> Staff { get; set; }
}

public class PresenterLoginPanel {

    private IViewLoginPanel _iViewLoginPanel;

    public PresenterLoginPanel(IViewLoginPanel panel) 
    { 
        _iViewLoginPanel = panel;
        SomeFunction();
    }

    public void SomeFunction() 
    {
        List<Person> loginStaff = new List<Person>(); 

        loginStaff.Add(new Person{FirstName = "John", LastName = "Doe"});

        _iViewLoginPanel.Staff = loginStaff;
    }

    public IViewLoginPanel ViewLoginPanel
    {
        get { return _iViewLoginPanel; }
    }
}

[TestFixture]
public class PresenterLoginPanelTests
{
    [Test]
    public void When_The_Presenter_Is_Created_Then_All_CP_Staff_Is_Added_To_Dropdown()
    {
        var _mockViewLoginPanel = new Mock<IViewLoginPanel>(MockBehavior.Strict);
        _mockViewLoginPanel.SetupAllProperties();

        PresenterLoginPanel target = new PresenterLoginPanel(_mockViewLoginPanel.Object);

        _mockViewLoginPanel.VerifySet(x => x.Staff = It.IsAny<List<Person>>());

        Assert.AreEqual(5, _mockViewLoginPanel.Object.Staff.Count);
    }

}
6 голосов
/ 07 февраля 2011

Вы можете легко сделать это с помощью самого Moq (даже если у вас еще нет ссылки на ожидаемый объект результата) - просто используйте метод It.Is(..):

_mockViewLoginPanel.VerifySet(x => x.Staff = It.Is<List<Person>>(staff => staff.Count == 5));
_mockViewLoginPanel.VerifySet(x => x.Staff = It.Is<List<Person>>(staff => staff[0].FirstName == "John"));
1 голос
/ 19 января 2011

Это проверяет, что количество сотрудников должно быть больше 0, что должен быть хотя бы один элемент, который не равен нулю, и есть хотя бы один элемент, имя которого равно Джо. если вы хотите сравнить объекты, вам нужно добавить компаратор.

Assert.AreNotEqual(this._mockViewLoginPanel.Object.Staff.Count, 0);
Assert.AreNotEqual(this._mockViewLoginPanel.Object.Staff.All(x => x == null), true);
Assert.AreEqual(this._mockViewLoginPanel.Object.Staff.Any(x => x.FirstName == "Joe"), true);
...