使用 C#(Client Library v3)对 Google Drive API 进行单元和集成测试?
Unit and Integration Testing for Google Drive API using C# (Client Library v3)?
我正在编写一个小型库,它使用 Google Drive API v3 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();
}
对于单元测试,它包含几个依赖项(可能会使用工厂方法模式进行重构):
- 列表请求
- 文件列表
集成测试还有很多问题:
- 我应该如何验证此类服务?
- 即使经过身份验证,它也会污染真正的经过身份验证的驱动器帐户。
- 如何在其他人之间共享测试?
- 如果没有互联网连接,测试将无法通过。
Entity Framework Core 是否有类似 "In-Memory" 的提供程序?
如何使 Google 驱动单元和集成测试易于管理?
所以有了 Enterprise,您就走运了。
假设示例项目如下:
- 安装了一个 nuget 包
Google.Apis.Drive.v3
- 使用以下列表添加了 class:
这是实际的程序
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 框架的强大功能对此处的所有内容进行单元测试,而无需连接到互联网、google 驱动器、帐户等
- 添加 Microsoft 测试项目(注意:仅 dll 在这里不起作用)
- 在测试项目中,安装相同的nuget包。
为您的 classes 所在的库生成伪造程序集(在本例中,Google.Apis.Drive.v3
和 Google.Apis
,您使用的是来自两者的类型):
编写单元测试:
像这样
[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);
}
}
}
我正在编写一个小型库,它使用 Google Drive API v3 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();
}
对于单元测试,它包含几个依赖项(可能会使用工厂方法模式进行重构):
- 列表请求
- 文件列表
集成测试还有很多问题:
- 我应该如何验证此类服务?
- 即使经过身份验证,它也会污染真正的经过身份验证的驱动器帐户。
- 如何在其他人之间共享测试?
- 如果没有互联网连接,测试将无法通过。
Entity Framework Core 是否有类似 "In-Memory" 的提供程序? 如何使 Google 驱动单元和集成测试易于管理?
所以有了 Enterprise,您就走运了。
假设示例项目如下:
- 安装了一个 nuget 包
Google.Apis.Drive.v3
- 使用以下列表添加了 class:
这是实际的程序
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 框架的强大功能对此处的所有内容进行单元测试,而无需连接到互联网、google 驱动器、帐户等
- 添加 Microsoft 测试项目(注意:仅 dll 在这里不起作用)
- 在测试项目中,安装相同的nuget包。
为您的 classes 所在的库生成伪造程序集(在本例中,
Google.Apis.Drive.v3
和Google.Apis
,您使用的是来自两者的类型):编写单元测试:
像这样
[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);
}
}
}