ok()在单元测试中返回null

本文关键字:返回 null 单元测试 ok | 更新日期: 2023-09-27 18:11:50

我最近调到了公司的一个新项目。我的任务是为我们的一个REST API控制器编写单元测试。控制器实现System.Web.Http.ApiController接口。我正在使用Moq,这是我第一次使用这个很酷的小库。我的问题是当我调用

IHttpActionResult result = Ok();

在控制器中,调用Ok()返回null。这只发生在我从单元测试中调用这个方法的时候。如果我使用Swagger直接调用我的方法,它会像预期的那样工作。

我认为可能是Moq语句我用来设置控制器参数/控制器本身是搞乱控制器的实例化,使继承的接口方法不可访问?下面是我用来设置单元测试的代码:

//Mock ICrmService to return an Id for a created company
var crmCacheService = new Mock<ICrmCacheService>();
var crmService = new Mock<ICrmService>();
crmCacheService.Setup(x => x.CreateSubscription(It.IsAny<CreateSubscriptionModel>())).Returns(true);
crmService.Setup(x => x.CreateSubscription(It.IsAny<CreateSubscriptionModel>())).Returns(ReturnedSubscriptionId);
var controller = new Mock<SubscriptionController>(crmService.Object, crmCacheService.Object);
IHttpActionResult actionResult = controller.Object.CreateSubscriptions(Guid.NewGuid().ToString(), 1);

有没有人知道为什么这会使调用Ok()返回null?我如何设置它,以便调用Ok()将返回System.Web.Http.Results.OkResult的正常结果?

ok()在单元测试中返回null

假定您的控制器是在此场景中测试的主题,在这种情况下,您根本不想模拟它,而是使用真实的实例(具有模拟的依赖项):

var controller = new SubscriptionController(crmService.Object, crmCacheService.Object);

由于你目前正在模拟它,并且由于Ok()方法在ApiController中是虚拟的,Moq将能够覆盖它并将这样做。因为默认的模拟行为是覆盖所有返回默认值的内容(MockBehavior.Loose),所以您将得到一个空返回值。

如果你真的想模拟它并从Ok()返回一个值,我认为你不会这样做,你可以使用Setup让它传递到真正的方法(在许多其他事情中,比如指定你想要获得的返回值):

controller.Setup(x => x.Ok()).CallBase();

Mock类有一个名为CallBase的属性来控制是否覆盖所有虚拟方法的默认行为。你可以很容易地说:

controller.CallBase = true;

更多详细信息请访问:https://stackoverflow.com/a/43319142/5675763