var controller = new Mock<JobOfferController>(context);
controller.Setup(m => m.UploadCvToAzureStorage(It.IsAny<IFormFile>()))
.Returns(Task.FromResult("cv-url"));
这部分代码返回以下错误:“ System.NotSupportedException:在非虚拟(在VB中可重写)成员成员上的无效设置:m => m.UploadCvToAzureStorage(It.IsAny())”。有任何解决方法的想法吗?
答案 0 :(得分:0)
Moq不会模拟具体类的非虚拟成员,因为它无法覆盖为实现设置而运行的代码。您需要模拟该类实现的接口。
如果您有这个:
public interface IJobOfferController
{
Task<string> UploadCvToAzureStorage(IFormFile file);
}
public class JobOfferController : IJobOfferController
{
public Task<string> UploadCvToAzureStorage(IFormFile file) => throw new NotImplementedException();
}
那么您将被设置为:
public void SetUp()
{
//this is trying to mock the concrete class and will fail
var controller = new Mock<JobOfferController>(context);
controller.Setup(m => m.UploadCvToAzureStorage(It.IsAny<IFormFile>()))
.Returns(Task.FromResult("cv-url"));
//This Mocks the interface and sets up a return value for that interface
var mockController = new Mock<IJobOfferController>();
mockController.Setup(m => m.UploadCvToAzureStorage(It.IsAny<IFormFile>()))
.Returns(Task.FromResult("cv-url"));
}
此外,当您在模拟异步方法时,可以删除.FromResult
并仅使用ReturnsAsync
controller.Setup(m => m.UploadCvToAzureStorage(It.IsAny<IFormFile>()))
.ReturnsAsync("cv-url");
或
如果您的控制器没有接口,另一种选择是使您的控制器的方法虚拟化,以便Moq可以通过您的设置覆盖它:
public class JobOfferController : IJobOfferController
{
public virtual Task<string> UploadCvToAzureStorage(IFormFile file) => throw new NotImplementedException();
}
//now the setup works
var controller = new Mock<JobOfferController>(context);
controller.Setup(m => m.UploadCvToAzureStorage(It.IsAny<IFormFile>()))
.ReturnsAsync("cv-url");