C# Returnsasync(null)在VS15中使用Moq进行单元测试时创建生成错误
当我在Visual Studio中的C单元测试方法中使用C# Returnsasync(null)在VS15中使用Moq进行单元测试时创建生成错误,c#,unit-testing,asynchronous,moq,C#,Unit Testing,Asynchronous,Moq,当我在Visual Studio中的C单元测试方法中使用ReturnsAsync(null)(使用Moq)时,我得到错误: “以下方法或属性之间的调用不明确” 然后是具有不同参数的ReturnsAsync方法列表。我知道这是由于ReturnsAsync函数被重载造成的。但是,当我在同事的计算机上运行相同的单元测试时,它运行时没有任何错误。有人知道为什么会这样吗?有人知道如何解决这个问题吗 此外,当我构建时,会收到以下警告: 所有引用*******的软件包必须安装nuget软件包Microsoft
ReturnsAsync(null)
(使用Moq
)时,我得到错误:
“以下方法或属性之间的调用不明确”
然后是具有不同参数的ReturnsAsync
方法列表。我知道这是由于ReturnsAsync
函数被重载造成的。但是,当我在同事的计算机上运行相同的单元测试时,它运行时没有任何错误。有人知道为什么会这样吗?有人知道如何解决这个问题吗
此外,当我构建时,会收到以下警告:
所有引用*******的软件包必须安装nuget软件包Microsoft.Bcl.Build
这会有什么影响吗?在Moq
ReturnsExtensions
类中有两种ReturnsAsync
扩展方法。它们有以下参数:
(this IReturns<TMock, Task<TResult>> mock, TResult value)
(this IReturns<TMock, Task<TResult>> mock, Func<TResult> valueFunction)
或者可以传递空值
string s = null;
... ReturnsAsync(s);
问题是编译器根据其参数类型和传递的参数类型选择要调用的重载方法。它被称为方法重载解析。但它的意思是“没有值”,同时它本身也不携带类型信息。如果没有类型,编译器不知道调用哪个重载方法,因此它抱怨“调用不明确” 当您有文本“Hello world”时,您(编译器)知道它有一个值(文本“Hello world”),它的类型是字符串。但是在
null
的情况下,类型信息丢失–它可能是没有值的字符串、没有值的委托或例如没有值的自定义引用类型
正如Sergey提到的,有两种重载方法:
(this IReturns<TMock, Task<TResult>> mock, TResult value)
(this IReturns<TMock, Task<TResult>> mock, Func<TResult> valueFunction)
另一方面,正如Sergey提到的,您可以将null
赋值到一个类型化变量中,并传递:
string x = null;
….ReturnAsync(x);
通过这种方式,您已经将
null
与特定类型(本例中为字符串)链接,因此编译器将再次知道要使用哪个重载。示例如何显式传递值
GetTokenClient.Setup(e =>
e.GetToken(It.IsAny<GetTokenParams>(),It.IsAny<CancellationToken>())
).ReturnsAsync(
(GetTokenParams GetTokenParams, CancellationToken CancellationToken) =>
new BaseResult<GetTokenResult>() { IsSuccess = true }
);
GetTokenClient.Setup(e=>
e、 GetToken(It.IsAny(),It.IsAny())
).ReturnsAsync(
(GetTokenParams GetTokenParams,CancellationToken CancellationToken)=>
new BaseResult(){IsSuccess=true}
);
完全可以使用ReturnAsync(null)
。检查具有不明确调用的方法-这些方法是在哪里定义的。@SergeyBerezovskiy它说当null是一个参数时ReturnsAsync方法具有不明确调用。是的,您已经在问题中说明了我应该检查哪些方法?所有重载的returnasync方法?所有带单参数的重载方法。您能给我们这些方法的签名吗?或者您可以传递RetursAsync(默认值(字符串))
或者,如果您在升级后有很多这样的错误,并且不想麻烦转换为不同的返回类型:ReturnsAsync(()=>null)
string x = null;
….ReturnAsync(x);
GetTokenClient.Setup(e =>
e.GetToken(It.IsAny<GetTokenParams>(),It.IsAny<CancellationToken>())
).ReturnsAsync(
(GetTokenParams GetTokenParams, CancellationToken CancellationToken) =>
new BaseResult<GetTokenResult>() { IsSuccess = true }
);