如何将Mock设置用于可空类型

时间:2012-09-07 11:44:33

标签: c# testing moq nullable

我有一个具有可为空参数的接口,如

Result<Notice> List(int offset, int limit, Guid? publicationId, Guid? profileId, DateTime? toDate, ListingOrder order);

这就是我试图模仿这个方法的方法

mockNoticesClient.Setup(c => c.List(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<Nullable<Guid>>(), It.IsAny<Nullable<Guid>>(), It.IsAny<Nullable<DateTime>>(), Data.Notices.ListingOrder.DateDesc)).Returns(dataNotices);

然后尝试使用方法时

var results = this.noticesClient.List(0, 100, null, profileId, latestNoticeTime, Data.Notices.ListingOrder.DateDesc);

每当抛出此异常时运行此行

... threw an exception of type 'System.NullReferenceException' ... {System.NullReferenceException}

我尝试了一些不同的组合,比如在参数中使用带有null的setup,但这也不起作用。我使用的是Moq 4.0.10827,这是最新版本(目前)。

修改 noticesClient的构造函数接受dataNoticesClient

的接口
public Client(Data.Notices.INotices noticesClient)

并像这样初始化

mockNoticesClient = new Mock<Data.Notices.INotices>();
noticesClient = new Client(mockNoticesClient.Object);

mockNoticesClient.Setup(c => c.List(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<Nullable<Guid>>(), It.IsAny<Nullable<Guid>>(), It.IsAny<Nullable<DateTime>>(), It.IsAny<Data.Notices.ListingOrder>())).Returns(dataNotices);

mockNoticesClient.Setup(c => c.List(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<Guid?>(), It.IsAny<Guid?>(), It.IsAny<DateTime?>(), It.IsAny<Data.Notices.ListingOrder>())).Returns(dataNotices);

2 个答案:

答案 0 :(得分:1)

这是提出问题(moq)时moq 4.0.10827库中的错误,但已解决here。现在可以使用Nullable<T>进行设置,并使用null进行调用,效果很好。

public interface INullable
{
    int Method(Guid? guid);
}

var mock = new Mock<INullable>();
mock.Setup(m => m.Method(It.IsAny<Guid?>())).Returns(6);
int a = mock.Object.Method(null); // a is 6

答案 1 :(得分:0)

我会调试此测试并检查以下内容:

Data.Notices.ListingOrder.DateDesc

前三个值中的一个可能为null,因此抛出NullReferenceException

顺便说一下,这样的链接可能表明存在设计缺陷,请参阅Law of Demeter