最小起订量:回调无效。带参数的方法设置不能调用带参数的回调,不使用回调
Moq: Invalid callback. Setup on method with parameters cannot invoke callback with parameters not using Callback
接口:
Task<ServiceResponse<string>> GetJSON<T>(FileRequest request, FileItemsSerializer<T> serializer = null, CsvConfiguration configuration = null, ClassMap<T> mapper = null) where T: class, new();
最小起订量设置:
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/"));
});
错误信息是
System.ArgumentException HResult=0x80070057 Message=Invalid
callback. Setup on method with 4 parameter(s) cannot invoke callback
with different number of parameters (1). Source=Moq StackTrace:
at
Moq.MethodCall.<>c__DisplayClass22_0.g__ValidateCallback|4(Delegate
callback) in C:\projects\moq4\src\Moq\MethodCall.cs:line 311 at
Moq.MethodCall.SetReturnComputedValueBehavior(Delegate valueFactory)
in C:\projects\moq4\src\Moq\MethodCall.cs:line 256 at
Moq.Language.Flow.NonVoidSetupPhrase2.Returns[T1](Func
2
valueExpression) in
C:\projects\moq4\src\Moq\Language\Flow\NonVoidSetupPhrase.cs:line 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/"));
});
由于 getJSON 的最后 3 个参数默认为 null。
我的问题是:为什么不工作和returns错误信息。我究竟做错了什么?我试图将其设置为类似于
Moq: Invalid callback. Setup on method with parameters cannot invoke callback with parameters
谢谢
您的代码无法正常工作,因为您使用的是 Returns
重载,它允许您获取提供给调用的参数,但您没有提供类型,也没有提供他们都。这与它们是否具有默认值无关,而是您没有提供 Moq 期望的定义。
可能有几种方法可以解决这个问题。给定:
var adFileServiceMock = new Mock<IAdFileService>();
var expectedMockResponse = ServiceResponse<string>.Create("Json Data", "http://test.com/", "Json Data", "http://test.com/");
- 总是return那个特定的实例:
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));
- 使用工厂,(在这种情况下,我只是 return 每次都使用相同的实例)
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));
当我 return 取决于提供给调用的 values/objects 时,我会这样做。
您必须指定类型。为了简洁起见,我在这里偷懒并使用了 It.IsAnyType
和 object
。我通常会使用特定类型或泛型类型参数。
最后,鉴于您正在 return 执行一项任务,我猜您正在使用异步进程,因此请考虑使用 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);
工作 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 { }
接口:
Task<ServiceResponse<string>> GetJSON<T>(FileRequest request, FileItemsSerializer<T> serializer = null, CsvConfiguration configuration = null, ClassMap<T> mapper = null) where T: class, new();
最小起订量设置:
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/"));
});
错误信息是
System.ArgumentException HResult=0x80070057 Message=Invalid callback. Setup on method with 4 parameter(s) cannot invoke callback with different number of parameters (1). Source=Moq StackTrace:
at Moq.MethodCall.<>c__DisplayClass22_0.g__ValidateCallback|4(Delegate callback) in C:\projects\moq4\src\Moq\MethodCall.cs:line 311 at Moq.MethodCall.SetReturnComputedValueBehavior(Delegate valueFactory) in C:\projects\moq4\src\Moq\MethodCall.cs:line 256 at Moq.Language.Flow.NonVoidSetupPhrase2.Returns[T1](Func
2 valueExpression) in C:\projects\moq4\src\Moq\Language\Flow\NonVoidSetupPhrase.cs:line 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/"));
});
由于 getJSON 的最后 3 个参数默认为 null。
我的问题是:为什么不工作和returns错误信息。我究竟做错了什么?我试图将其设置为类似于
Moq: Invalid callback. Setup on method with parameters cannot invoke callback with parameters
谢谢
您的代码无法正常工作,因为您使用的是 Returns
重载,它允许您获取提供给调用的参数,但您没有提供类型,也没有提供他们都。这与它们是否具有默认值无关,而是您没有提供 Moq 期望的定义。
可能有几种方法可以解决这个问题。给定:
var adFileServiceMock = new Mock<IAdFileService>();
var expectedMockResponse = ServiceResponse<string>.Create("Json Data", "http://test.com/", "Json Data", "http://test.com/");
- 总是return那个特定的实例:
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));
- 使用工厂,(在这种情况下,我只是 return 每次都使用相同的实例)
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));
当我 return 取决于提供给调用的 values/objects 时,我会这样做。
您必须指定类型。为了简洁起见,我在这里偷懒并使用了 It.IsAnyType
和 object
。我通常会使用特定类型或泛型类型参数。
最后,鉴于您正在 return 执行一项任务,我猜您正在使用异步进程,因此请考虑使用 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);
工作 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 { }