【问题标题】:How could I Mock this code?我怎么能模拟这段代码?
【发布时间】:2015-06-01 12:08:20
【问题描述】:

我想开始模拟一些代码,但我不确定如何去做。我已经阅读了一些教程,但我无法将它应用到我的代码中(这背后可能有一个原因)。 我正在使用 NUnit 和起订量。 (我已经删除了所有其他方法,所以我只给你看一个)。

API接口:

public interface IApiRequest
{
    Task<T> ExecuteAsync<T>(RestRequest request);
}

我想模拟的方法:

public async Task<UpcomingMovies> GetUpcomingMovies(int page)
        {
            var request = new RestRequest
            {
                Resource = "movie/upcoming",
            };
            request.AddParameter("page", page.ToString());
            request.AddParameter("language", "en");

            var api = new ApiRequest();

            return await api.ExecuteAsync<UpcomingMovies>(request);
        }

我不确定如何模拟这个。

更新:

现在这是一个有效的测试吗?

 Mock<IApiRequest> mock = new Mock<IApiRequest>();
        mock.Setup(x => x.ExecuteAsync<UpcomingMovies>(It.IsAny<RestRequest>()))
            .Returns(Task.FromResult<UpcomingMovies>(new UpcomingMovies()));

【问题讨论】:

  • 你不应该新建你的 api,因为你不能在测试中模拟它。最好传入构造函数,这样在你的测试中你可以传入模拟。

标签: c# unit-testing mocking nunit moq


【解决方案1】:

如果你想模拟 ExecutAsync 方法,你可以这样做:

Mock<IApiRequest> mock = new Mock<IApiRequest>();
mock.Setup(x => x.ExecuteAsync<UpcomingMovies>(It.IsAny<RestRequest>()))
    .Returns(Task.FromResult<UpcomingMovies>(/** whatever movies **/));

如果您想模拟特定请求,请将 It.IsAny&lt;RestRequest&gt;() 替换为对您的请求的引用。

为了有效地测试你的课程,你需要这样的东西:

public class MyClass
{
    public MyClass(IApiRequest api)
    {
        this.api = api; 
    }    

    public async Task<UpcomingMovies> GetUpcomingMovies(int page)
    {
        var request = new RestRequest
        {
            Resource = "movie/upcoming",
        };
        request.AddParameter("page", page.ToString());
        request.AddParameter("language", "en");

        return await api.ExecuteAsync<UpcomingMovies>(request);
    }
}

测试

[Test]
public async Task MyTest()
{
    var expectedMovies = new UpcomingMovies(); // or whatever movies you need

    Mock<IApiRequest> mock = new Mock<IApiRequest>();
mock.Setup(x => x.ExecuteAsync<UpcomingMovies>(It.IsAny<RestRequest>()))
    .Returns(Task.FromResult<UpcomingMovies>(expectedMovies));

    var myClass = new MyClass(mock.Object);
    var result = await myClass.GetUpcomingMovies(1);

    Assert.IsTrue(expectedMovies == result);    
}

【讨论】:

  • 这是一个有效的模拟,但是你需要从你的测试方法中调用GetUpcomingMovies,它需要是async
  • 好的,但是我怎么称呼它呢?如果我调用它,那么模拟将不会做任何事情?
  • 我添加了一个示例测试,希望对您有所帮助。
  • 这是一个很好的例子。非常感谢 Ned,它让我了解了它是如何更好地工作的!
猜你喜欢
  • 2017-08-15
  • 2020-05-24
  • 2019-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多