简体   繁体   English

使用moq验证列表

[英]verifying a list using moq

Given the calling code 给出调用代码

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

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

this._iViewLoginPanel.Staff = loginStaff;

What is the syntax for verifying that there exists a staff by the name of john doe and that there is at least one staff being set? 验证是否存在名为john doe的员工并且至少有一名员工被设置的语法是什么? Currently, all the examples that I've seen are pretty basic, using only It.IsAny or Staff = some basic type but none actually verify data within complex types like lists. 目前,我看到的所有示例都非常基本,仅使用It.IsAny或Staff =某些基本类型,但实际上没有验证复杂类型(如列表)中的数据。

My assert looks like 我的断言看起来像

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

which only checks the type given to the setter but not the size or items within the list itself. 它只检查给定位器的类型,而不检查列表本身的大小或项目。 I've tried to do something like this: 我试过这样的事情:

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

But that tells me that the lambda statement body cannot be converted to an expression tree. 但这告诉我lambda语句体不能转换为表达式树。 Then i got the idea of putting the statement body into a function and running that, but during runtime I get: 然后我得到了将语句体放入函数并运行它的想法,但在运行时我得到:

System.ArgumentException: Expression is not a property setter invocation. System.ArgumentException:Expression不是属性setter调用。

Update: In light of the first two answers to use assert, I tried that method but found that even after setting Staff to a non null list, it still shows up in debug as null. 更新:根据使用assert的前两个答案,我尝试了该方法,但发现即使将Staff设置为非空列表,它仍然在调试中显示为null。 So this is how the full test looks 所以这就是完整测试的样子

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

And somewhere within the constructor of PresenterLoginPanel 并且在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;
    }
}

When i debug to the next line, this._iViewLoginPanel.Staff is null which is what's causing the null exception in the assert. 当我调试到下一行时, this._iViewLoginPanel.Staff为null,这是导致断言中出现空异常的原因。

Rather than using the mock's methods, you can use NUnit methods to make assertions about the contents of the mock object. 您可以使用NUnit方法对mock对象的内容进行断言,而不是使用mock的方法。

Once you've assigned the list to the object and verified it has been set, use assertions to check specifics, such as the item count and that the first object matches what you expect it to contain. 将列表分配给对象并验证它已设置后,使用断言检查细节,例如项目计数以及第一个对象与您期望包含的对象匹配。

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

Edit 编辑

After further investigation this comes down to Mock Behaviour. 经过进一步调查后,这归结为模拟行为。 The properties Staff and Person weren't setup properly. StaffPerson的属性设置不正确。

Do setup them up, alter your mock creation to this: 设置它们,将模拟创建改为:

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

A complete code listing of a demo is: 演示的完整代码清单是:

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

}

You could easily accomplish this with Moq itself (also when you don't already have a reference to the expected result object) - just use the It.Is(..) method: 您可以使用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"));

This checks that the staff count should be more than 0, that there should be at least one item that is not null and there is at least one item that has first name equal to Joe. 这将检查人员计数应该大于0,应该至少有一个非空的项目,并且至少有一个项目的名字等于Joe。 if you want to compare the objects, you'll have to add a comparer. 如果要比较对象,则必须添加比较器。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM