c# - 我们如何使用第三方 API 为 Webapi 创建单元测试

标签 c# api unit-testing asp.net-web-api nunit

我正在使用 Nunit 创建单元测试。我有 webapi 项目并使用一些第三方 api,下面是我正在使用的代码块之一。

在下面的函数中,您可以看到我正在返回 facebook graph api 以字符串格式返回的 json 数据。至于 Unit Test Assert 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;
        }

最佳答案

考虑抽象化您的依赖项(在本例中为第 3 方 API)并将它们注入(inject)到它们的依赖类中。这将允许更好地模拟您的单元测试和整体更灵活/可维护的架构。

以您当前的函数为例,抽象看起来像这样。

public interface IFacebookService {
    public string GetFriends();
}

public interface ITokenProvider {
    public string GetAccessToken();
}

此接口(interface)的实现具有连接到第 3 方服务的实际代码。

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 Controller 。

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. :(");
    }
}

对于独立的单元测试,您现在可以模拟已抽象的第 3 方 API。我正在使用 Moq 模拟第 3 方抽象。

[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 
    }
}

以上测试现在允许您单独测试 Controller ,而无需直接调用实际的第 3 方 API。

关于c# - 我们如何使用第三方 API 为 Webapi 创建单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39828669/

相关文章:

unit-testing - 开发网站时进行单元测试?

c# - 如何在一段时间后强行关闭c#中的进程?

c# - 锯齿状阵列的通用打印

c# - 自定义数据表输出

json - 在 Swift 中获取 API 数据

objective-c - 访问 DOM Webkit Objective C

java - 使用 Rest Assured GET 方法获取错误代码 503

python - 如何测试 pytest fixture 本身?

C# : Unable to print data as unicode characters from MYSQL database

unit-testing - 我如何期望单元测试失败?