【发布时间】:2016-06-27 20:04:06
【问题描述】:
背景
我有一个使用 NHibernate 将对象持久保存到数据库的类。当您为没有设置 ID 的对象调用 MergeEntity 时,NHibernate 在返回时使用 ID 填充该对象。为了确保我始终使用与 NHibernate 相同的对象,我将更新后的对象从我的“Save”函数传回。
问题
我正在尝试使用 Moq 模拟相同的行为,这通常非常直观且易于使用;但是,我在验证对 Save() 的调用是否使用正确的参数时遇到了一些问题。我想验证传入的对象的 ID 是否为零,然后由Save 函数正确设置。不幸的是,当我在Moq.Returns()函数中修改ID时,Moq.Verify函数使用的是修改后的值,而不是传入的ID值。
为了说明,这是一个非常基本的类(我重写了 ToString() 函数,因此我的测试输出将显示调用模拟的 Save() 时使用的 ID):
public class Class1
{
private readonly IPersistence _persistence;
/// <summary>Initializes a new instance of the <see cref="T:System.Object" /> class.</summary>
public Class1(IPersistence persistence)
{
_persistence = persistence;
}
public int Id { get; set; }
public void Save()
{
_persistence.Save(this);
}
public override string ToString()
{
return Id.ToString();
}
}
这是界面(非常简单):
public interface IPersistence
{
Class1 Save(Class1 one);
}
这是我认为应该通过的测试:
[TestFixture]
public class Class1Tests
{
[Test]
public void Save_NewObjects_IdsUpdated()
{
var mock = new Mock<IPersistence>();
mock.Setup(x => x.Save(It.IsAny<Class1>()))
.Returns((Class1 c) =>
{
// If it is a new object, then update the ID
if (c.Id == 0) c.Id = 1;
return c;
});
// Verify that the IDs are updated for new objects when saved
var one = new Class1(mock.Object);
Assert.AreEqual(0, one.Id);
one.Save();
mock.Verify(x => x.Save(It.Is<Class1>(o => o.Id == 0)));
}
}
不幸的是,它没有说明从未使用符合该条件的参数调用它。在模拟上对Save 的唯一调用是使用 ID 为 1 的对象。我已验证当对象进入 Returns 函数时,它们的 ID 为 0。如果我更新Returns() 函数中的值,我是否无法区分传入模拟的内容和更新的对象的内容?
【问题讨论】:
标签: c# unit-testing moq