在编写单元测试时,我们总是说我们需要确保代码始终与外部依赖项隔离。下面的 Moq 已用于提供一个模拟对象,而不是一个有效的流畅的 nhibernate 会话工厂。
public class and_saving_a_invalid_item_type :
when_working_with_the_item_type_repository
{
private Exception _result;
protected override void Establish_context()
{
base.Establish_context();
_sessionFactory = new Mock<ISessionFactory>();
_session = new Mock<ISession>();
_sessionFactory.Setup(sf => sf.OpenSession()).Returns(_session.Object);
_itemTypeRepository = new ItemTypeRepository(_sessionFactory.Object);
_session.Setup(s => s.Save(null)).Throws(new ArgumentNullException());
}
protected override void Because_of()
{
try
{
_itemTypeRepository.Save(null);
}
catch (Exception ex)
{
_result = ex;
}
}
[Test]
public void then_an_argument_null_exception_should_be_raised()
{
_result.ShouldBeInstanceOfType(typeof(ArgumentNullException));
}
}
实际实现如下所示。测试运行良好。但是如果没有将期望设置为 throw argumentnullexception,save 方法实际上会返回 NullReferenceException。关键是:单元测试是否会掩盖实际结果。虽然从单元测试的角度来看满足了要求,但在实现时并没有真正满足。
public class ItemTypeRepository : IItemTypeRepository
{
public int Save(ItemType itemType)
{
int id;
using (var session = _sessionFactory.OpenSession())
{
id = (int) session.Save(itemType);
session.Flush();
}
return id;
}
}