2015-09-25 59 views
1

我一定要考的是处理特定的事件,并坚持它只读Mongo的数据库上的投影(我使用的是官方的C#蒙戈驱动程序):单元测试时,成员隐藏

public class MyObjectProjection : IHandleMessages<RegisteredEvent> 
{ 
    private MongoCollection<MyObjectView> _collection; 
    private MyObjectView item; 

    public MyObjectProjection (MongoDatabase db) 
    { 
     _collection = db.GetCollection<MyObjectView>("my-object"); 
    } 

    public void Handle(RegisteredEvent message) 
    { 
     item = new MyObjectView(); 
     item.Id = message.Id; 

     // some code omitted     

     _collection.Save(item); 
    } 
} 

我需要单元测试Handle方法,因为:

  • 我不想进行集成测试。数据库和收集被嘲笑,所以保存不实
  • 我只是想测试的项目的消息映射
  • 成员是隐藏的,我不想让他们更多的分享范围

我应该使用替代解决方案而不是反射或友好装配吗?这种情况下的最佳做法是什么? 现在我的测试是这样的:

[TestMethod] 
    public void TestMethod1() 
    { 
     // ARRANGE - some code omitted 
     databaseMock 
      .Setup(x => x.GetCollection<MyObjectView>(It.IsAny<string>())) 
      .Returns(collection); 

     collectionMock 
      .Setup(x => x.Save(It.IsAny<MyObjectView>())) 
      .Returns(It.IsAny<WriteConcernResult>); 

     // ACT 
     var handler = new MyObjectProjection(database); 
     handler.Handle(evt); 

     // ASSERT 
     // nothin' to assert here! 
    } 

这个工作,但我没有什么时候完成Handle方法断言。

回答

0

这种情况下的最佳做法是什么?

最佳做法是使成员可见。您有什么特别的理由需要隐藏会员吗?

然后,您可以断言对传递给Save方法参数:

MyObjectView objectView; 

    collectionMock 
     .Setup(x => x.Save(It.IsAny<MyObjectView>())) 
     .Callback<MyObjectView>((obj) => objectView= obj) 
     .Returns(It.IsAny<WriteConcernResult>); 

    Assert.That(objectView.Id, Is.EqualTo(evt.Id)); 
    //assert other properties 
+0

我宁愿尽可能地限制自己,而且我真的不喜欢为了可测试性而增加可视性的想法。我想要的就是这个,通过模拟测试。 –

0

那么,您的Handle()方法通过调用Save()方法与集合进行交互。因此,你可以期望传递给handle方法,该元素具有正确的ID集:

collectionMock.Verify(x=>x.Save(It.Is<MyObjectView>(v => v.Id == 5)), Times.Once,"save should be called with object with Id = 5"); 

我这里假设传递到Handle()evt有和5码的编号没有测试过,但我认为像这会做的伎俩。

+0

ID是我手动映射的唯一领域,其他均为AutoMapper的东西,我觉得不舒服明知只有测试过的东西是我比其他人更信任的东西:) –