【问题标题】:Unit and Integration Testing for Google Drive API using C# (Client Library v3)?使用 C#(客户端库 v3)对 Google Drive API 进行单元和集成测试?
【发布时间】:2017-03-26 07:06:56
【问题描述】:

我正在编写一个使用 Google Drive API v3 Client Library for C# 的小型库。 对我来说,这会带来很多痛苦,因为我不能为此目的使用 TDD 样式。

完成这项工作的常规方法如下所示:

internal async Task<Google.Apis.Drive.v3.Data.FileList> ReadFileList(string parentId, string pageToken, int pageSize)
{
    // Define parameters of request.
    var listRequest = this.driveService.Files.List();
    listRequest.PageSize = pageSize;
    listRequest.Q = "mimeType='application/vnd.google-apps.folder' and ('" + parentId + "' in parents)";
    listRequest.Fields = "nextPageToken, files(id, name)";
    listRequest.PageToken = pageToken;

    // List files.
    return await listRequest.ExecuteAsync();
}

对于单元测试,它包含几个依赖项(可能会使用工厂方法模式重构):

  1. 列表请求
  2. 文件列表

对于集成测试还有更多问题:

  1. 我应该如何验证此类服务?
  2. 即使经过身份验证,它也会污染真实的经过身份验证的云端硬盘帐户。
  3. 如何在其他人之间共享测试?
  4. 没有互联网连接就无法通过测试。

是否有类似实体框架核心的“内存中”提供程序? 可以做些什么来使 Google Drives 单元和集成测试易于管理?

【问题讨论】:

  • 这是因为您的代码与第 3 部分 SDK 紧密耦合。在您的代码和第 3 方 api 之间添加一个抽象层,这应该允许您控制更多的灵活性和模拟代码。
  • 这可能有帮助,也可能没有帮助gist.github.com/LindaLawton/b576d21924139902b7163d0441636a20
  • @Nikosi 是的,这是一个很好的建议。我已经创建了一个单独的图层。但我仍然担心潜在的问题。
  • 你使用什么版本的 Visual Studio?
  • @zaitsman 我使用 Visual Studio 2015 Enterprise。没有意识到它可能会影响某些东西。

标签: c# unit-testing google-drive-api integration-testing


【解决方案1】:

所以,有了 Enterprise,你就走运了。

假设一个示例项目是这样的:

  1. 安装了一个nuget包Google.Apis.Drive.v3
  2. 添加了一个具有以下列表的类:

这是实际程序

 public class Class1
  {
    public async Task<Google.Apis.Drive.v3.Data.FileList> ReadFileList(string parentId, string pageToken, int pageSize)
    {
      // get the service somehow.
      var ds = new DriveService();

      var listRequest = ds.Files.List();
      listRequest.PageSize = pageSize;
      listRequest.Q = "mimeType='application/vnd.google-apps.folder' and ('" + parentId + "' in parents)";
      listRequest.Fields = "nextPageToken, files(id, name)";
      listRequest.PageToken = pageToken;

      // List files.
      return await listRequest.ExecuteAsync();
    }
  }

我们可以利用 Microsoft Fakes 框架的强大功能对这里的所有内容进行单元测试,而无需连接到互联网、谷歌驱动器、帐户等。

  1. 添加一个 Microsoft 测试项目(注意:这里只使用一个 dll 是行不通的)
  2. 在测试项目中,安装相同的 nuget 包。
  3. 为您的类所在的库生成假程序集(在本例中,Google.Apis.Drive.v3Google.Apis,您正在使用两者中的类型):

  4. 编写单元测试:

像这样

  [TestClass]
  public class UnitTest1
  {
    [TestMethod]
    public void TestMethod1()
    {
      using (Microsoft.QualityTools.Testing.Fakes.ShimsContext.Create())
      {
        int? usedPageSize = 0;
        var usedQ = string.Empty;
        var usedFields = string.Empty;
        var usedPageToken = string.Empty;

        Google.Apis.Drive.v3.Fakes.ShimFilesResource.ShimListRequest.AllInstances.PageSizeSetNullableOfInt32 =
          (request, i) => usedPageSize = i;
        Google.Apis.Drive.v3.Fakes.ShimFilesResource.ShimListRequest.AllInstances.QSetString = (request, s) => usedQ = s;
        Google.Apis.Drive.v3.Fakes.ShimDriveBaseServiceRequest<Google.Apis.Drive.v3.Data.FileList>.AllInstances
          .FieldsSetString = (request, s) => usedFields = s;

        Google.Apis.Drive.v3.Fakes.ShimFilesResource.ShimListRequest.AllInstances.PageTokenSetString = (request, s) => usedPageToken = s;
        Google.Apis.Requests.Fakes.ShimClientServiceRequest<Google.Apis.Drive.v3.Data.FileList>.AllInstances
            .ExecuteAsync =
          request =>
            Task.FromResult(
              new FileList
                {
                  ETag = "hello",
                  Files = new List<File> { new File { Name = "imafile" } },
                  IncompleteSearch = false,
                  Kind = "Somekind",
                  NextPageToken = null
                });

        Google.Apis.Drive.v3.Fakes.ShimFilesResource.AllInstances.List = resource => (FilesResource.ListRequest)FormatterServices.GetUninitializedObject(typeof(FilesResource.ListRequest));
        Google.Apis.Drive.v3.Fakes.ShimDriveService.Constructor = service => { }; // do not init the class
        Google.Apis.Drive.v3.Fakes.ShimDriveService.AllInstances.FilesGet = service => (FilesResource)FormatterServices.GetUninitializedObject(typeof(FilesResource));

        var target = new Class1();
        var result = target.ReadFileList("parent", "token", 42).Result;

        Assert.AreEqual(42, usedPageSize);
        Assert.AreEqual("mimeType='application/vnd.google-apps.folder' and ('parent' in parents)", usedQ);
        Assert.AreEqual("nextPageToken, files(id, name)", usedFields);
        Assert.AreEqual("token", usedPageToken);
        Assert.AreEqual(1, result.Files.Count);
        Assert.AreEqual("imafile", result.Files[0].Name);
        Assert.AreEqual("hello", result.ETag);
        Assert.IsFalse(result.IncompleteSearch.Value);
        Assert.AreEqual("Somekind", result.Kind);
        Assert.IsNull(result.NextPageToken);
      }
    }
  }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-04
    • 2013-12-07
    • 1970-01-01
    • 1970-01-01
    • 2012-11-21
    相关资源
    最近更新 更多