界面:
Task<ServiceResponse<string>> GetJSON<T>(FileRequest request, FileItemsSerializer<T> serializer = null, CsvConfiguration configuration = null, ClassMap<T> mapper = null) where T: class, new();
Run Code Online (Sandbox Code Playgroud)
起订量设置:
Mock<IAdFileService> mock = new Mock<IAdFileService>();
mock.Setup(x => x.GetJSON(
It.IsAny<FileRequest>(),
It.IsAny<FileItemsSerializer<dynamic>>(),
It.IsAny<CsvConfiguration>(),
It.IsAny<ClassMap<dynamic>>())
).Returns<ServiceResponse<string>>((a) => {
return Task.FromResult(ServiceResponse<string>.Create(
"Json Data",
"http://test.com/",
"Json Data",
"http://test.com/"));
});
Run Code Online (Sandbox Code Playgroud)
错误信息是
System.ArgumentException HResult=0x80070057 Message=回调无效。具有 4 个参数的方法的设置无法调用具有不同数量参数的回调 (1)。源= Moq StackTrace:
位于 Moq.MethodCall.<>c__DisplayClass22_0.g__ValidateCallback|4(委托回调),位于 C:\projects\moq4\src\Moq\MethodCall.cs:Moq.MethodCall.SetReturnCompulatedValueBehavior(委托 valueFactory)中的第 311 行C:\projects\moq4\src\Moq\MethodCall.cs: 第 256 行位于2.Returns[T1](FuncC:\projects\moq4\src\Moq\Language\Flow\NonVoidSetupPhrase.cs 中的 Moq.Language.Flow.NonVoidSetupPhrase 2 valueExpression):第 281 行
我想用
mock.Setup(x => x.GetJSON<dynamic>(It.IsAny<FileRequest>())
).Returns<ServiceResponse<string>>(
(a) => {
return Task.FromResult(ServiceResponse<string>.Create(
"Json Data",
"http://test.com/",
"Json Data",
"http://test.com/"));
});
Run Code Online (Sandbox Code Playgroud)
由于 getJSON 的最后 3 个参数默认为 null。
我的问题是:为什么不起作用并返回错误消息。我究竟做错了什么?我尝试将其设置为类似于
“起订量:无效回调”。带参数的方法设置无法调用带参数的回调
谢谢
rgv*_*lee 10
您的代码不起作用,因为您正在使用Returns重载,该重载允许您获取提供给调用的参数,但您没有提供类型,也没有提供所有参数。这并不是说它们有默认值,而是您没有提供 Moq 期望的定义。
可能有几种方法可以解决这个问题。鉴于:
var adFileServiceMock = new Mock<IAdFileService>();
var expectedMockResponse = ServiceResponse<string>.Create("Json Data", "http://test.com/", "Json Data", "http://test.com/");
Run Code Online (Sandbox Code Playgroud)
adFileServiceMock
.Setup(x => x.GetJSON<It.IsAnyType>(It.IsAny<FileRequest>(), It.IsAny<FileItemsSerializer<It.IsAnyType>>(), It.IsAny<CsvConfiguration>(), It.IsAny<ClassMap<It.IsAnyType>>()))
.Returns(Task.FromResult(expectedMockResponse));
Run Code Online (Sandbox Code Playgroud)
adFileServiceMock
.Setup(x => x.GetJSON<It.IsAnyType>(It.IsAny<FileRequest>(), It.IsAny<FileItemsSerializer<It.IsAnyType>>(), It.IsAny<CsvConfiguration>(), It.IsAny<ClassMap<It.IsAnyType>>()))
.Returns(() => Task.FromResult(expectedMockResponse));
Run Code Online (Sandbox Code Playgroud)
这就是我通常做的事情。
adFileServiceMock
.Setup(x => x.GetJSON<It.IsAnyType>(It.IsAny<FileRequest>(), It.IsAny<FileItemsSerializer<It.IsAnyType>>(), It.IsAny<CsvConfiguration>(), It.IsAny<ClassMap<It.IsAnyType>>()))
.Returns((FileRequest providedFileRequest, object providedFileItemsSerializer, CsvConfiguration providedCsvConfiguration, object providedClassMap) => Task.FromResult(expectedMockResponse));
Run Code Online (Sandbox Code Playgroud)
当我返回的内容取决于提供给调用的值/对象时,我会这样做。
您必须指定类型。为了简洁起见,我在这里偷懒并使用了It.IsAnyType和object。我通常会使用特定类型或泛型类型参数。
最后,考虑到您正在返回一个任务,猜测您正在使用异步进程,因此请考虑使用ReturnsAsync
adFileServiceMock
.Setup(x => x.GetJSON<It.IsAnyType>(It.IsAny<FileRequest>(), It.IsAny<FileItemsSerializer<It.IsAnyType>>(), It.IsAny<CsvConfiguration>(), It.IsAny<ClassMap<It.IsAnyType>>()))
.ReturnsAsync(() => expectedMockResponse);
Run Code Online (Sandbox Code Playgroud)
工作 LINQPad 示例:
async void Main()
{
var adFileServiceMock = new Mock<IAdFileService>();
var expectedMockResponse = ServiceResponse<string>.Create("Json Data", "http://test.com/", "Json Data", "http://test.com/");
// adFileServiceMock
// .Setup(x => x.GetJSON<It.IsAnyType>(It.IsAny<FileRequest>(), It.IsAny<FileItemsSerializer<It.IsAnyType>>(), It.IsAny<CsvConfiguration>(), It.IsAny<ClassMap<It.IsAnyType>>()))
// .Returns(Task.FromResult(expectedMockResponse));
//
// adFileServiceMock
// .Setup(x => x.GetJSON<It.IsAnyType>(It.IsAny<FileRequest>(), It.IsAny<FileItemsSerializer<It.IsAnyType>>(), It.IsAny<CsvConfiguration>(), It.IsAny<ClassMap<It.IsAnyType>>()))
// .Returns(() => Task.FromResult(expectedMockResponse));
//
// adFileServiceMock
// .Setup(x => x.GetJSON<It.IsAnyType>(It.IsAny<FileRequest>(), It.IsAny<FileItemsSerializer<It.IsAnyType>>(), It.IsAny<CsvConfiguration>(), It.IsAny<ClassMap<It.IsAnyType>>()))
// .Returns((FileRequest providedFileRequest, object providedFileItemsSerializer, CsvConfiguration providedCsvConfiguration, object providedClassMap) => Task.FromResult(expectedMockResponse));
adFileServiceMock
.Setup(x => x.GetJSON<It.IsAnyType>(It.IsAny<FileRequest>(), It.IsAny<FileItemsSerializer<It.IsAnyType>>(), It.IsAny<CsvConfiguration>(), It.IsAny<ClassMap<It.IsAnyType>>()))
.ReturnsAsync(() => expectedMockResponse);
var adFileService = adFileServiceMock.Object;
var mockResponse = await adFileService.GetJSON(new FileRequest(), new FileItemsSerializer<Foo>(), new CsvConfiguration(), new ClassMap<Foo>());
mockResponse.Should().BeSameAs(expectedMockResponse);
}
// You can define other methods, fields, classes and namespaces here
public interface IAdFileService
{
Task<ServiceResponse<string>> GetJSON<T>(FileRequest request, FileItemsSerializer<T> serializer = null, CsvConfiguration configuration = null, ClassMap<T> mapper = null) where T : class, new();
}
public class ServiceResponse<T>
{
public static ServiceResponse<T> Create(string a, string b, string c, string d)
{
return new ServiceResponse<T>();
}
}
public class FileRequest { }
public class FileItemsSerializer<T> { }
public class CsvConfiguration { }
public class ClassMap<T> { }
public class Foo { }
Run Code Online (Sandbox Code Playgroud)