How to mock a method returning Task<IEnumerable<T>> with Task<List<T>>?

僤鯓⒐⒋嵵緔 提交于 2019-12-10 12:42:53

问题


I'm attempting to set up a unit test initializer (in Moq) where an interface method is being mocked:

public interface IRepository
{
    Task<IEnumerable<myCustomObject>> GetSomethingAsync(string someStringParam);
}

...

[TestInitialize]
public void Initialize()
{
    var repoMock = new Mock<IRepository>();

    var objectsList = new List<myCustomObject>() {
        new myCustomObject("Something"), 
        new myCustomObject("Otherthing")
    }

    repoMock.Setup<Task<IEnumerable<myCustomObject>>>(
        rep => rep.GetSomethingAsync("ThisParam")
    ).Returns(Task.FromResult(objectsList)); //error here
}

The issue I'm having is I can't figure out how to get the method to return my objectsList. In practice this of course works fine because List implements IEnumerable, but it doesn't seem to work when wrapped in a Task, in Moq. The error I get is on the Returns() method:

Argument 1: cannot convert from 'System.Threading.Tasks.Task<
  System.Collections.Generic.List<myCustomObject>>'
to 'System.Threading.Tasks.Task<
  System.Collections.Generic.IEnumerable<myCustomObject>>'

As a workaround I can create another method that simply creates the List<myObj> and returns it as IEnumerable<myObj>, but I feel like there must be another way to handle this that is cleaner.

So, how would I do this without having to create the helper method?


回答1:


You need to specify the <IEnumerable<myCustomObject>> on the Task.FromResult, like this:

[TestInitialize]
public void Initialize()
{
    var repoMock = new Mock<IRepository>();

    var objectsList = new List<myCustomObject>() {
        new myCustomObject("Something"), 
        new myCustomObject("Otherthing")
    }

    repoMock.Setup<Task<IEnumerable<myCustomObject>>>(
        rep => rep.GetSomethingAsync("ThisParam")
    ).Returns(Task.FromResult<IEnumerable<myCustomObject>>(objectsList));
}

Alternatively you could declare your objectList as <IEnumerable<myCustomObject>> before assigning it from the List<myCustomObject>. Making the previous suggestion not required.




回答2:


You could generically cast your original object:

IEnumerable<myCustomObject> objectsList = new List<myCustomObject>() {
    new myCustomObject("Something"), 
    new myCustomObject("Otherthing")
};


来源:https://stackoverflow.com/questions/37439166/how-to-mock-a-method-returning-taskienumerablet-with-tasklistt

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!