C# 如何测试第三方API。我应该创建单元测试还是集成测试?

C# 如何测试第三方API。我应该创建单元测试还是集成测试?,c#,unit-testing,asp.net-core,integration-testing,C#,Unit Testing,Asp.net Core,Integration Testing,我正在使用.NETCore2.0创建WebAPI。我正在使用ActiveDirectory图形API()执行创建新用户的操作。我用这样的接口创建了IADGraphService interface IADGraphService { bool CreateUser(UserModel model); IList<UserModel> GetUsers(); bool UpdateUser(UserModel model); bool DeleteUs

我正在使用.NETCore2.0创建WebAPI。我正在使用ActiveDirectory图形API()执行创建新用户的操作。我用这样的接口创建了IADGraphService

interface IADGraphService 
{
    bool CreateUser(UserModel model);
    IList<UserModel> GetUsers();
    bool UpdateUser(UserModel model);
    bool DeleteUser(string userObjectId);
}
或者这种接口的单元测试实现:

// arrange
......
var fakeHttpClient = new Mock<IHttpClient>();
fakeHttpClient.Setup(x => x.PostAsync(url, userModelContent)).Returns(mockJsonResult);
var service = new ADGraphService(fakeHttpClient.Object);

// act
var result = service.CreateUser(new UserModel { Email = "test@example.com", .......});

// assert 
result.Should().Be(true);
//排列
......
var fakeHttpClient=new Mock();
Setup(x=>x.PostAsync(url,userModelContent)).Returns(mockJsonResult);
var service=new-ADGraphService(fakeHttpClient.Object);
//表演
var result=service.CreateUser(新用户模型{Email=”test@example.com", .......});
//断言
result.Should()为(true);

在这种情况下应该使用哪一个?

如果需要测试类ADGraphService的行为,应该对模拟的HttpClient使用单元测试。对于与web服务的测试集成,您应该在HttpClient上而不是在您的类ADGraphService上编写集成测试。

一个好策略是不要模拟您不拥有的代码。您应该有一层集成测试,实际调用Azure AD,并证明它正在按照您的意愿进行操作

为详细说明该战略:

  • 围绕第三方代码编写一个薄包装,只公开代码实际需要的操作。(看起来您已经使用ADGraphService/IADGraphService完成了此操作。)
  • 编写测试瘦包装器(ADGraphService)的集成测试,并证明其公共操作确实按照您的预期方式工作
  • 然后,当您测试更高级别的对象时,可以使用IADGraphService的模拟。您已经证明(通过集成测试)您了解包装器应该如何工作,因此可以模拟合理的行为
在我看来,您的集成测试正走在正确的轨道上。您正在编写自己的接口,并且只公开代码所需的行为。您的集成测试证明,这些方法实际上达到了您的目的——如果Microsoft做出突破性的更改,您的测试将告诉您


然后,当您测试更高级别的代码(使用IADGraphService的代码)时,您可以模拟IADGraphService,因为它是您自己的代码,您可以安全地模拟它。

如果您需要集成测试,为什么不呢?看起来不错。只有CreateUser是arrange的一部分,而不是act@Serghei只是想知道,这是最好的选择吗。我在谷歌上搜索了很多文章,他们告诉我应该模拟第三方API提供的结果。如果你要模拟第三方API,比如WebService等,那将是一个单元测试,而不是我日常工作中的集成测试,我会使用这两个测试。你们可以在这里读到,我对问题稍加修改。实际上我心里有一个单元测试,我把它添加到了我的问题中。问题是哪一个更适合这种情况?单元测试还是集成测试?第二个单元测试更好,因为您想测试我在下面回答的类ADGraphService的行为
// arrange
......
var fakeHttpClient = new Mock<IHttpClient>();
fakeHttpClient.Setup(x => x.PostAsync(url, userModelContent)).Returns(mockJsonResult);
var service = new ADGraphService(fakeHttpClient.Object);

// act
var result = service.CreateUser(new UserModel { Email = "test@example.com", .......});

// assert 
result.Should().Be(true);