I do not know if you know InternalsVisibleToAttribute
I have used on a project https://github.com/ignatandrei/WorldBankAPi,that deals with World Bank API to get information
Let’s take an example: Countries: http://api.worldbank.org/countries?format=json
I have had a class CountriesRepository,that deals with transforming countries Json from WorldBank to Country classes. How can I test it WITHOUT relying on reading data from the internet ?
Simple:
1. Make an interface to grab JSON,IJSonData
    public interface IJsonData
    {
        Task<string> JsonData(int page = 1);
    }
2. Make a class JSONCountry that reads JSON from HTTP and implements IJSonData
3. Make the CountryRepository class with 2 constructors – one with IJSonData and the default calling JSONCountry
[assembly: InternalsVisibleTo("WorldBank.Test")]
namespace WorldBank.Repository
{
    public class CountriesRepository
    {
        private IJsonData data;
        public CountriesRepository():this(new JsonCountries())
        {
        }
//this is internal - could not see by outside projects with exception of WorldBank.Test
//see InternalsVisibleTo above
        internal CountriesRepository(IJsonData data)
        {
            this.data = data;
        }
    }
}
Optional: when testing manually,save the json into same files on the hard disk – you will need for point 5
4. The code that will use CountryRepository in official way will use the default – will not see the one with IJSonData
var c = new CountriesRepository(); var data = c.GetCountries().Result;
5. The testing code will define another class JSONFromHard that implements IJSonData and reads data from Hard
class JsonFromHard : IJsonData
{
//code to read files from disk 
// you have saved those when testing manually 
//see point 2 the optional part 
}
6. Because I have defined InternalsVisibleToAttribute to the WorldBank.Test,the Test dll can see the constructor with IJSonData and then it class with JSONFromHard – and I have no dependecy on the Http
public void GetAndInterpretData()
        {
            //uses [assembly: InternalsVisibleTo("WorldBank.Test")]
            var c = new CountriesRepository(new JsonFromHard("Countries"));
            var data = c.GetCountries().Result;
            Assert.Equal(218,data.Length);
        }
You can download the project from https://github.com/ignatandrei/WorldBankAPi to see working.
Leave a Reply