Unit testing 将Generic.List强制转换为System.Threading.Task.Generic.List时出现问题
我正在尝试创建IMemoryCache.TryGetValue方法的模拟,但当它点击Unit testing 将Generic.List强制转换为System.Threading.Task.Generic.List时出现问题,unit-testing,asp.net-core,moq,xunit,Unit Testing,Asp.net Core,Moq,Xunit,我正在尝试创建IMemoryCache.TryGetValue方法的模拟,但当它点击cache.Get(cacheKey)时,返回以下错误: 无法将类型为'System.Collections.Generic.List`1[ConnectionModel]'的对象强制转换为类型为'System.Threading.Tasks.Task`1[System.Collections.Generic.List`1[ConnectionModel] 以下是模拟: private static Mock&
cache.Get(cacheKey)
时,返回以下错误:
无法将类型为'System.Collections.Generic.List`1[ConnectionModel]'的对象强制转换为类型为'System.Threading.Tasks.Task`1[System.Collections.Generic.List`1[ConnectionModel]
以下是模拟:
private static Mock<IMemoryCache> ConfigureMockCacheWithDataInCache(List<ConnectionsModel> auth0ConnectionsResponse)
{
object value = auth0ConnectionsResponse;
var mockCache = new Mock<IMemoryCache>();
mockCache
.Setup(x => x.TryGetValue(
It.IsAny<object>(), out value
))
.Returns(true);
return mockCache;
}
专用静态模拟配置MockCacheWithDataInCache(列出auth0ConnectionsResponse)
{
对象值=auth0ConnectionsResponse;
var mockCache=new Mock();
模拟缓存
.Setup(x=>x.TryGetValue(
It.IsAny(),out值
))
.返回(真);
返回mockCache;
}
以下是测试方法:
var connectionList = new List<ConnectionsModel>();
var connectionsModel= new ConnectionsModel()
{
id = "1",
name = "abc",
enabled_cons = new List<string>() { "test" }
};
connectionList.Add(connectionsModel);
var mockObject = ConfigureMockCacheWithDataInCache(connectionList);
var sut = new MyService(mockCache.Object);
// Act
var result = await sut.GetConnection(_clientId);
var connectionList=newlist();
var connectionsModel=新的connectionsModel()
{
id=“1”,
name=“abc”,
已启用\u cons=new List(){“test”}
};
connectionList.Add(connectionsModel);
var mockObject=ConfigureMockCacheWithDataInCache(connectionList);
var sut=newmyservice(mockCache.Object);
//表演
var result=wait sut.GetConnection(_clientId);
以下是它所点击的服务:
public async Task<ConnectionsModel> GetConnection(string clientId)
{
var connections = await _cacheService.GetOrSet("cacheKey", ()=> CallBack());
var connection = connections.FirstOrDefault();
return connection;
}
private async Task<List<ConnectionsModel>> CallBack()
{
string url = url;
_httpClient.BaseAddress = new Uri(BaseUrl);
var response = await _httpClient.GetAsync(url);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsAsync<List<ConnectionsModel>>();
}
公共异步任务GetConnection(字符串clientId)
{
var connections=wait_cacheService.GetOrSet(“cacheKey”,()=>CallBack());
var connection=connections.FirstOrDefault();
回路连接;
}
专用异步任务回调()
{
字符串url=url;
_httpClient.BaseAddress=新Uri(BaseUrl);
var response=await\u httpClient.GetAsync(url);
response.EnsureSuccessStatusCode();
return wait response.Content.ReadAsAsync();
}
以及缓存扩展方法:
public static T GetOrSet<T>(this IMemoryCache cache, string cacheKey, Func<T> getItemCallback, double cacheTimeout = 86000) where T : class
{
T item = cache.Get<T>(cacheKey);
if (item == null)
{
item = getItemCallback();
cache.Set(cacheKey, item, DateTime.Now.AddSeconds(cacheTimeout));
}
return item;
}
public static T GetOrSet(此IMemoryCache缓存,字符串cacheKey,Func getItemCallback,double cacheTimeout=86000),其中T:class
{
T item=cache.Get(cacheKey);
如果(项==null)
{
item=getItemCallback();
Set(cacheKey,item,DateTime.Now.AddSeconds(cacheTimeout));
}
退货项目;
}
在这一行之后,
T item=cache.Get(cacheKey);
我得到了上面提到的异常。如何解决这个问题?在扩展方法中,您调用的是getItemCallback()
而不等待。lambda调用服务中的回调方法,该方法是异步的,因此这也是异步的。因此,您将项设置为任务,并尝试将其作为列表返回
考虑创建扩展的额外重载,以允许使用异步API
public static async Task<T> GetOrSet<T>(this IMemoryCache cache, string cacheKey, Func<Task<T>> getItemCallback, double cacheTimeout = 86000) where T : class
{
T item = cache.Get<T>(cacheKey);
if (item == null)
{
item = await getItemCallback();
cache.Set(cacheKey, item, DateTime.Now.AddSeconds(cacheTimeout));
}
return item;
}
公共静态异步任务GetOrSet(此IMemoryCache缓存,字符串cacheKey,Func getItemCallback,双缓存超时=86000),其中T:class
{
T item=cache.Get(cacheKey);
如果(项==null)
{
item=等待getItemCallback();
Set(cacheKey,item,DateTime.Now.AddSeconds(cacheTimeout));
}
退货项目;
}
您正在传递任务并试图将其分配给任务结果的某个位置。请重新检查扩展方法的逻辑,但由于扩展不是异步的,因此需要对其进行重构。如何更改Func getItemCallBack(param中的0是否可等待?您不需要。返回值将是一个始终可等待的任务。但是,您也可以尝试传递一个异步lambdaasync()=>await Callback()
我尝试过async()=>await Callback()但同样的结果也是如此,@Nkosi是正确的。如果你有一个异步操作,你必须一直异步。这意味着你的扩展方法应该是异步的,任何调用它的东西也需要是异步的。另外,我已经根据你的另一个答案为这个扩展方法编写了一个模拟。这样好吗?对象预期d、 var mockCache=new Mock();var cachEntry=Mock.Of();mockCache.Setup(x=>x.TryGetValue(It.IsAny(),超出预期值))。返回(true);mockCache.Setup(x=>x.CreateEntry(It.IsAny()).Returns(cachEntry);return mockCache;@Ask乍一看就可以了。它对您的测试有效吗?
public static async Task<T> GetOrSet<T>(this IMemoryCache cache, string cacheKey, Func<Task<T>> getItemCallback, double cacheTimeout = 86000) where T : class
{
T item = cache.Get<T>(cacheKey);
if (item == null)
{
item = await getItemCallback();
cache.Set(cacheKey, item, DateTime.Now.AddSeconds(cacheTimeout));
}
return item;
}