我如何单元测试仅由NHibernate设置的受保护属性?

Dan*_* T. 11 c# nhibernate nunit unit-testing moq

我正在使用NHibernate来持久保存这个实体:

public class Store
{
    public int Id { get; protected set; }
    public int Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

请注意该Id属性如何具有受保护的setter.这是为了防止用户更改Idwhile仍然允许NHibernate在将Id其保存到数据库时分配它.

在我的一个单元测试中,我使用Moq和以下代码来模拟我的存储库:

var mock = new Mock<IRepository>();
mock.Setup(x => x.GetById<Store>(It.IsAny<int>()))
    .Returns(new Store { Value = "Walmart" }); // can't set the ID here

var store = Repository.GetById<Store>(5);
Assert.That(store.Id == 5);
Run Code Online (Sandbox Code Playgroud)

当我告诉Moq返回一个新Store实例时,我无法分配ID,并且单元测试失败.我该如何对这个属性进行单元测试?我不想更改属性的访问级别,因为我不希望用户手动更改它,但这正是我必须要做的,以便测试它.

Jef*_*ata 13

只是把它作为另一种方法抛出那里,你可以制作二传手protected internal:

public class Store
{
    public int Id { get; protected internal set; }
    public int Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

并使用InternalsVisibleTo属性:

[assembly: InternalsVisibleTo("StoreUnitTests")]
Run Code Online (Sandbox Code Playgroud)


aro*_*eer 11

如果你实际上没有测试Store类,那么模拟它,并使用SetupGet方法:

var mock = new Mock<IRepository>();
var mockStore = new Mock<Store>();
mock.Setup(x => x.GetById<Store>(It.IsAny<int>())).Returns(mockStore.Object);

mockStore.SetupGet(s => s.Id).Returns(5);
mockStore.SetupGet(s => s.Value).Returns("Walmart");

var store = Repository.GetById<Store>(5);
Assert.That(store.Id == 5);
Run Code Online (Sandbox Code Playgroud)


Jar*_*Par 7

在测试项目中创建一个Store允许自定义受保护属性的子类。

class TestableStore : Store { 
  public int TestableId { 
    get { return Id; }
    set { Id = value; }
  }
}
Run Code Online (Sandbox Code Playgroud)

然后设置单元测试以在需要构造Store对象时使用返回此实例。

mock
  .Setup(x => x.GetById<Store>(It.IsAny<int>()))
  .Returns(new TestableStore { Value = "Walmart", TestableId=42 }); 
Run Code Online (Sandbox Code Playgroud)