System.Threading.Tasks.Task.Factory.StartNew调用的Moq方法
本文关键字:调用 Moq 方法 StartNew Factory Threading Tasks Task System | 更新日期: 2023-09-27 18:19:51
我正在使用Moq编写单元测试。我有一个DataManager对象,它调用WCF来获取数据。我把这个注入我的控制器。然而,在控制器内部,对该DataManager中的方法的调用被封装在任务内部
System.Threading.Tasks.Task.Factory.StartNew<MyDataObject>(()=>
{
return DataManager.GetMyDataObject(userobj, recordid);
}
我用Moq为DataManager.GetMyDataObject创建了一个mock但是无论何时从控制器方法内部的该语句调用它则返回null。我在谷歌上搜索了很多,但大多数内容都是关于以Task作为返回签名的方法。
DataManager.GetMyDataObject是作为标准同步代码编写的。
我使用的是Moq v4.0.10827,怀疑我是否可以升级。
我正在尝试很多方法。。Moq似乎希望返回与方法签名匹配
_mockDataManager = new Mock<_mockDataManager>();
_mockDataManager.Setup(m => m.GetMyDataObject(It.IsAny<UserObj>(), It.IsAny<Guid>()))
然后又回来了?我也trid回调
_mockDataManager.Setup(m => System.Threading.Tasks.Task.FromResult(m.GetMyDataObject(It.IsAny<UserObj>(), It.IsAny<Guid>())
.Returns(System.Threading.Tasks.Task.FromResult(myData))
.Callback<MyDataObject>(o => myData = o);
myData = GetMyDataObject();
_mockDataManager.Setup(m => m.GetMyDataObject(It.IsAny<UserObj>(), It.IsAny<Guid>()).Returns(GetMyDataObject())
private GetMyDataObject() {
returns new DataSet(); //basically an empty dataset but not null
}
给定以下类:
public class MyDataObject { }
public class UserObj { }
public class DataManager
{
public virtual MyDataObject GetMyDataObject(UserObj userObj, Guid guid)
{
throw new NotImplementedException();
}
}
class SUT
{
public DataManager DataManager { get; private set; }
public SUT(DataManager dataManager)
{
DataManager = dataManager;
}
public void Method(UserObj userobj, Guid recordid)
{
var t = System.Threading.Tasks.Task.Factory.StartNew<MyDataObject>(()=>
{
return DataManager.GetMyDataObject(userobj, recordid);
});
t.Wait();
}
}
以下模型运行良好:
var mockDataManager = new Mock<DataManager>();
mockDataManager.Setup(m => m.GetMyDataObject(It.IsAny<UserObj>(), It.IsAny<Guid>()));
var sut = new SUT(mockDataManager.Object);
sut.Method(new UserObj(), Guid.Empty);
mockDataManager.VerifyAll();
两个陷阱:
在你发布的代码中,你使用
_mockDataManager = new Mock<_mockDataManager>();
应该是
_mockDataManager = new Mock<DataManager>(); // or whatever the name of the class is
也许这只是一个复制/粘贴错误,也许不是。
此外,由于您在此处使用Task
:
System.Threading.Tasks.Task.Factory.StartNew<MyDataObject>(()=>
{
return DataManager.GetMyDataObject(userobj, recordid);
}
它在DataManager
上调用GetMyDataObject
,您必须确保Task
在验证模拟设置之前完成。如果您从上面的代码中删除t.Wait();
,测试就会失败,因为VerifyAll
将在Task
启动并调用模拟对象中的GetMyDataObject
之前被调用。