I do not know if you know InternalsVisibleToAttribute
https://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.internalsvisibletoattribute%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396 .
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.