skip to Main Content

I am using Nunit for creating unit tests. I am having webapi project and using some third party api for Below is one of blocks of code i am using .

In Below function you can see i am returning json data returned by facebook graph api in String Format . As for Unit Test Assert IsEqual Check my both comparing objects will be using data from same api then Do I need to match them or Do I need to Do Testing for This type of project .

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

2

Answers


  1. I’d abstract out your message sending/retrieval, then unit test that in isolation & whichever class contains your GetFriends in isolation too, mocking out the message sending/retrieval.

    You should be doing unit testing for all projects, but the code needs to be designed in such a way where that is feasible. Currently this code is going to be difficult to test, as it’s spinning up HttpWebRequests, that needs to be isolated behind some sort of interface, called something like IRequestSender. I’d recommend Moq for mocking out interfaces, without mocking you’ll find testing is like banging your head against a wall.

    Login or Signup to reply.
  2. Look into abstracting your dependencies (in this case the 3rd party APIs) and injecting them into their dependent classes. This would allow for better mocking with your unit tests and overall a more flexible/maintainable architecture.

    Using your current function as an example, an abstraction would look something like this.

    public interface IFacebookService {
        public string GetFriends();
    }
    
    public interface ITokenProvider {
        public string GetAccessToken();
    }
    

    Where the implementation of this interface to have the actual code to connect to the 3rd party service.

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

    if you have an API controller that is dependent on that service, say for example.

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

    For isolated unit tests you can now mock the 3rd party API which has been abstracted. I am using Moq to mock up the 3rd party abstractions.

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

    The above test now allows you to test the controller in isolation without having to make direct calls to the actual 3rd party API.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search