C# System.Threading.Tasks.Task.Factory.StartNew调用的Moq方法
我正在使用Moq编写一个单元测试。我有一个DataManager对象,它调用WCF来获取数据。我把它注入我的控制器。但是,在控制器内部,对此DataManager中的方法的调用被包装在任务内部C# System.Threading.Tasks.Task.Factory.StartNew调用的Moq方法,c#,asp.net-mvc,moq,C#,Asp.net Mvc,Moq,我正在使用Moq编写一个单元测试。我有一个DataManager对象,它调用WCF来获取数据。我把它注入我的控制器。但是,在控制器内部,对此DataManager中的方法的调用被包装在任务内部 System.Threading.Tasks.Task.Factory.StartNew<MyDataObject>(()=> { return DataManager.GetMyDataObject(userobj, recordid); } System.Threading.
System.Threading.Tasks.Task.Factory.StartNew<MyDataObject>(()=>
{
return DataManager.GetMyDataObject(userobj, recordid);
}
System.Threading.Tasks.Task.Factory.StartNew(()=>
{
返回DataManager.GetMyDataObject(userobj,recordid);
}
我已经用Moq为DataManager.GetMyDataObject创建了一个模拟
但无论何时从控制器方法内部的该语句调用它
它返回空值。我在谷歌上搜索了很多东西,但大部分内容都是处理以Task作为返回签名的方法
DataManager.GetMyDataObject是作为标准同步代码编写的
我正在使用Moq v4.0.10827,我怀疑我是否可以升级
我尝试了很多方法。Moq似乎期望返回与方法签名匹配
_mockDataManager = new Mock<_mockDataManager>();
_mockDataManager.Setup(m => m.GetMyDataObject(It.IsAny<UserObj>(), It.IsAny<Guid>()))
\u mockDataManager=new Mock();
_mockDataManager.Setup(m=>m.GetMyDataObject(It.IsAny(),It.IsAny())
然后又回来了?我还回了电话
_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
}
\u mockDataManager.Setup(m=>System.Threading.Tasks.Task.FromResult(m.GetMyDataObject(It.IsAny(),It.IsAny())
.Returns(System.Threading.Tasks.Task.FromResult(myData))
.Callback(o=>myData=o);
myData=GetMyDataObject();
_mockDataManager.Setup(m=>m.GetMyDataObject(It.IsAny(),It.IsAny())。返回(GetMyDataObject())
私有GetMyDataObject(){
返回新的DataSet();//基本上是一个空数据集,但不是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();
}
}
它在
DataManager
上调用GetMyDataObject
,在验证模拟设置之前,必须确保任务完成。如果要删除t.Wait()从上面我的代码来看,测试将失败,因为VerifyAll
将在任务启动并调用模拟对象中的GetMyDataObject
之前被调用。DataManager.GetMyDataObject怎么样?你是如何模拟它的?向我们展示那段代码。isDataManager.GetMyDataObject
是一个静态调用?_mockDataManager=new Mock();不,它不是静态方法或类。它是一个注入控制器的实例,我过去在需要Task.Factory.StartNew
时就是这样做的,它通过一个接口为此创建一个适配器。基本上,这只是在下面调用Task.Factory.StartNew
,还允许您模拟对StartNe的调用w
。这是因为我们不希望任何测试启动新任务,但同时希望确保我们的代码实际调用StartNew
,同步且可测试。谢谢。这是一个拼写错误,实际上我有Task.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
System.Threading.Tasks.Task.Factory.StartNew<MyDataObject>(()=>
{
return DataManager.GetMyDataObject(userobj, recordid);
}