如何用第三方api为Webapi创建单元测试?
本文关键字:创建 单元测试 Webapi 何用 第三方 api | 更新日期: 2023-09-27 18:11:19
我使用Nunit创建单元测试。我有webapi项目,并使用一些第三方api以下是我正在使用的代码块之一。
在下面的函数中,你可以看到我正在返回json数据由facebook图形api返回字符串格式。至于单元测试断言IsEqual检查我的两个比较对象将使用来自相同api的数据,然后我需要匹配它们还是我需要为这种类型的项目做测试。
public string getfriends(string accesstoken)
{
string retVal = "";
string url = API_BaseUrl + "/me/invitable_friends?&access_token=" + accesstoken;
System.Net.HttpWebRequest request = System.Net.WebRequest.Create(url) as System.Net.HttpWebRequest;
System.Net.HttpWebResponse response = null;
try
{
using (response = request.GetResponse() as System.Net.HttpWebResponse)
{
System.IO.StreamReader reader = new System.IO.StreamReader(response.GetResponseStream());
retVal = reader.ReadToEnd();
}
}
catch (Exception ex)
{
}
return retVal;
}
考虑抽象您的依赖项(在本例中是第三方api)并将它们注入到它们的依赖类中。这将允许更好地模拟你的单元测试,并且总体上更灵活/可维护的架构。
以您当前的函数为例,抽象将看起来像这样。
public interface IFacebookService {
public string GetFriends();
}
public interface ITokenProvider {
public string GetAccessToken();
}
其中实现这个接口要有实际的代码来连接到第三方服务。
public class FacebookService : IFacebookService
private string accesstoken;
private string API_BaseUrl;
public FacebookService(ITokenProvider tokens, IUrlProvider urls) {
accessToken = tokens.GetAccessToken();
API_BaseUrl = url.GetBaseUrl();
}
public string Getfriends() {
string retVal = "";
string url = API_BaseUrl + "/me/invitable_friends?&access_token=" + accesstoken;
System.Net.HttpWebRequest request = System.Net.WebRequest.Create(url) as System.Net.HttpWebRequest;
System.Net.HttpWebResponse response = null;
try {
using (response = request.GetResponse() as System.Net.HttpWebResponse) {
System.IO.StreamReader reader = new System.IO.StreamReader(response.GetResponseStream());
retVal = reader.ReadToEnd();
}
}
catch (Exception ex)
{
}
return retVal;
}
}
如果你有一个依赖于该服务的API控制器,例如:
public class FriendsController : ApiController {
IFacebookService facebook;
public FriendsController(IFacebookService facebook) {
this.facebook = facebook;
}
[HttpGet]
public IHttpActionResult GetFacebookFriends() {
var friends = facebook.GetFriends();
if(!string.IsNullOrWhiteSpace(friends)) {
return Ok(friends);
}
return NotFound("You have no friends. :(");
}
}
对于独立的单元测试,你现在可以模拟已经被抽象的第三方API。我正在使用Moq来模拟第三方抽象。
[TestClass]
public class FriendsControllerTests {
[TestMethod]
public void GetFacebookFriendsTest() {
//Arrange
var facebook = Mock.Of<IFacebookService>();
var facebookMock = Mock.Get(facebook);
facebookMock.Setup(m => m.GetFriends()).Returns("{json of friends}");
var sut = new FriendsController(facebook);
//Act
var actionResult = sut.GetFacebookFriends();
//Assert
//...do your assertions here
}
}
上面的测试现在允许您独立测试控制器,而不必直接调用实际的第三方API。
我将抽象出您的消息发送/检索,然后单独进行单元测试&无论哪个类也隔离地包含GetFriends,模拟消息发送/检索。
你应该为所有的项目做单元测试,但是代码需要以这样一种可行的方式来设计。目前,这段代码将很难测试,因为它旋转HttpWebRequests,需要被隔离在某种接口后面,称为IRequestSender之类的东西。我推荐Moq模拟接口,如果没有模拟,你会发现测试就像把你的头撞到墙上。