简体   繁体   中英

Unit test a method reading file

I search on net but couldnt find proper solution. My issue is I want to test my readFileToList method which is make a filter in the file(csv) and; create List of objects. Its okay in my application I try to test this with following method in unit test project:

        [TestMethod]
        public void readingFile()
        {
           HomeController controller = new HomeController();
           List<City> result = controller.readFileToList("sample_data.csv", Pairing.Of("cityname", "Antalya"));
           Assert.AreEqual(83, result.Count);//"cityname" equals to Antalya is 83 
        }

I debug this test and see the error in of the function; "HttpRuntime.AppDomainAppPath" return null, and I wonder how can I handle this and next coming issues for testing this method. I just want this test check count of generated file equals to expected count(83)

function:

public List<City> readFileToList(string filename, params KeyValuePair<string, object>[] queryparams)
        {
            string fullName = Path.Combine(HttpRuntime.AppDomainAppPath, "App_Data", filename);
            string[] lines = System.IO.File.ReadAllLines(fullName);
            IQueryable<City> cities = lines.Skip(1).Select(l => new City
            {
                name = l.Split(',')[0],
                cityCode = Convert.ToInt32(l.Split(',')[1]),
                district = l.Split(',')[2],
                zipCode = l.Split(',')[3],
            }).AsQueryable();
            foreach (KeyValuePair<string, object> item in queryparams)
            {
                if (item.Key == "cityname" && item.Value.ToString() != "0")
                    cities = cities.Where(w => w.cityCode.ToString() == item.Value.ToString());               
            }
               return cities.ToList();
        }

Assuming that you don't worry much about unittesting actual Input/Output , I'd say that the method you are trying to test has not one, but at least two responsibilities :

  1. Determine the server path of some file.
  2. Parse that file.

You may leave it as it is if your testing framework supports mocking of static members (you can just mock/fake the HttpRuntime.AppDomainAppPath to return some test file path) or abstract the HttpRuntime , but I'd recommend you to split readFileToList into two methods:

  1. GetCsvFileServerPath(String csvFileName) - that will Path.Combine(HttpRuntime.AppDomainAppPath, "App_Data", filename);
  2. public List<City> ReadFileToList(string fullServerFilePath, params KeyValuePair<string, object>[] queryparams) that processes a file at the fullServerFilePath returned by the GetCsvFileServerPath(String csvFileName)

So the second method can be relatively easily unittested without additional changes .

PS: If you have some time and want to do more proper unittesting, you may try to abstract file IO , or at least separate file reading and processing , because ReadFileToList both reads and processes the file, that is more difficult to test.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM