Joe*_*Joe 5 .net c# unit-testing moq mocking
给出调用代码
List<Person> loginStaff = new List<Person>();
loginStaff.add(new Person{FirstName = "John", LastName = "Doe"});
this._iViewLoginPanel.Staff = loginStaff;
Run Code Online (Sandbox Code Playgroud)
验证是否存在名为john doe的员工并且至少有一名员工被设置的语法是什么?目前,我看到的所有示例都非常基本,仅使用It.IsAny或Staff =某些基本类型,但实际上没有验证复杂类型(如列表)中的数据.
我的断言看起来像
this._mockViewLoginPanel.VerifySet(x=> x.Staff = It.IsAny<List<Person>>());
Run Code Online (Sandbox Code Playgroud)
它只检查给定位器的类型,而不检查列表本身的大小或项目.我试过这样的事情:
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;
});
Run Code Online (Sandbox Code Playgroud)
但这告诉我lambda语句体不能转换为表达式树.然后我得到了将语句体放入函数并运行它的想法,但在运行时我得到:
System.ArgumentException:Expression不是属性setter调用.
更新: 根据使用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);
}
Run Code Online (Sandbox Code Playgroud)
并且在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;
}
}
Run Code Online (Sandbox Code Playgroud)
当我调试到下一行时,this._iViewLoginPanel.Staff为null,这是导致断言中的空异常的原因.
Mic*_*ins 14
您可以使用NUnit方法对mock对象的内容进行断言,而不是使用mock的方法.
将列表分配给对象并验证它已设置后,使用断言检查细节,例如项目计数以及第一个对象与您期望包含的对象匹配.
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]));
Run Code Online (Sandbox Code Playgroud)
编辑
经过进一步调查后,这归结为模拟行为.属性Staff和Person设置不正确.
设置它们,将模拟创建改为:
var _mockViewLoginPanel = new Mock<IViewLoginPanel>(MockBehavior.Strict);
_mockViewLoginPanel.SetupAllProperties();
Run Code Online (Sandbox Code Playgroud)
演示的完整代码清单是:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
小智 7
您可以使用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"));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9196 次 |
| 最近记录: |