如何模拟返回Task <ienumerable <t>&gt;的方法与任务<list <t>&gt;?

时间:2016-05-25 13:47:55

标签: c# unit-testing moq

我正在尝试设置一个单元测试初始化​​器(在Moq中),其中一个接口方法被模拟:

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
}

我遇到的问题是我无法弄清楚如何让方法返回objectsList。在实践中,这当然可以正常工作,因为List实现了IEnumerable,但是当它包含在Moq中的Task中时它似乎不起作用。我得到的错误是Returns()方法:

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

作为一种解决方法,我可以创建另一种方法,只需创建List<myObj>并将其作为IEnumerable<myObj>返回,但我觉得必须有另一种方法来处理更干净。

那么,如何在不创建辅助方法的情况下完成此操作?

2 个答案:

答案 0 :(得分:23)

您需要在<IEnumerable<myCustomObject>>上指定Task.FromResult,如下所示:

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

或者,您可以在objectList<IEnumerable<myCustomObject>>分配之前将List<myCustomObject>声明为from bs4 import BeautifulSoup, SoupStrainer html = '''<html> <body> <p class="fixedfonts"> <a href="A.pdf">LINK1</a> </p> <h2>Results</h2> <p class="fixedfonts"> <a href="B.pdf">LINK2</a> </p> <p class="fixedfonts"> <a href="B.pdf">LINK2</a> </p> <p class="fixedfonts"> <a href="C.pdf">LINK3</a> </p> </body> </html>''' # at this point html contains the code as string # parse the HTML file dat = html.split("Result") need = dat[1] soup = BeautifulSoup(html.replace('\n', ''), parse_only=SoupStrainer('a')) # kill all script and style elements for script in soup(["script", "style"]): script.extract() # rip it out links = list() for link in soup: if link.has_attr('href'): links.append(link['href'].replace('%20', ' ')) n_links = list() for i in set(links): if need.count(i) > 0: for x in range(1, need.count(i) + 1): n_links.append(i) print(n_links) 。不需要提出先前的建议。

答案 1 :(得分:6)

您可以通常投射原始对象:

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