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

时间:2015-10-30 12:56:41

标签: c# asp.net-mvc moq

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

System.Threading.Tasks.Task.Factory.StartNew<MyDataObject>(()=>
{
   return DataManager.GetMyDataObject(userobj, recordid);
}

我用Moq为DataManager.GetMyDataObject创建了一个模拟器 但每当从控制器方法内部的这个语句中调用它 它返回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
}

1 个答案:

答案 0 :(得分:1)

鉴于以下类别:

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);
}

GetMyDataObject上调用DataManager,您必须确保在之前Task完成验证您的模拟设置。如果您要从我上面的代码中删除t.Wait();,则测试会失败,因为VerifyAll会在Task启动之前调用,并在模拟对象中调用GetMyDataObject