C# System.Threading.Tasks.Task.Factory.StartNew调用的Moq方法

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.

我正在使用Moq编写一个单元测试。我有一个DataManager对象,它调用WCF来获取数据。我把它注入我的控制器。但是,在控制器内部,对此DataManager中的方法的调用被包装在任务内部

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怎么样?你是如何模拟它的?向我们展示那段代码。is
DataManager.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);
}