Should all classes be tested?

I am trying to write unit tests for a new project that I created, and I had a problem when I cannot understand how the class that I intend to write can actually be checked. I have simplified the class I'm trying to write below to give you an idea of โ€‹โ€‹what I'm trying to achieve.

So, I have an XML parser that will simply access the XML file from the given URL, retrieve the data I need and return it as an object. Thus, my code will look something like this (validation and population are not complete yet, but you get this idea):

public UserDetails ParseUserDetails(string request, string username, string password) { var response = new XmlDocument(); response.Load(string.Format(request + "?user={0}&password={1}", username, password)); // Validation checks return new UserDetails { // Populate object with XML nodes }; } 

My class is currently not being tested. I can't make fun of the load to throw a WebException to see how my class handles errors, and until I go through a valid URL, it will always throw an exception when I run tests against this class. I also cannot check the returned data from the class, since I cannot mock the XML document, since it is loaded from another URL.

I could break this down into a mocking object that extracts XML from a URL and calls it something like IXmlDocumentLoader, but later I come across the same problem where I have a class like this:

 public class XmlDocumentLoader : IXmlDocumentLoader { public XmlDocument LoadXmlDocument(string request, string username, string password) { var response = new XmlDocument(); response.Load(string.Format(request + "?user={0}&password={1}", username, password)); return response; } } 

This will make the ParseUserDetails method more reliable, but now the XmlDocumentLoader class is not tested. So I just moved the problem elsewhere? My question really is whether all classes should be testable, or do I not understand how unit testing is being tested?

+6
source share
3 answers

This is probably an โ€œopinionโ€, and therefore likely to be closed.

But I will give you an offer.

Share everything. Use the principle "an object must do only one thing." Upload a file - this is one, confirm that this is another. If you separate both options, you can check both.

You can test your download system on a common file (it is not necessary to be a production site) and check if the system works. And you can provide a โ€œfake fileโ€ to validate the check, which should also not be a production file.

Both tests will give you an idea of โ€‹โ€‹how well your code is working.

+4
source

The XmlDocument.Load (string filename) documentation on MSDN defines the filename parameter as follows:

filename: URL for the file containing the downloadable XML document. The URL may be a local file or an HTTP URL (web address).

(my emphasis)

This way your code is fully validated if your ParseUserDetails tags pass something like file://C:/path/to/my/test/file as the request parameter. They might look something like this:

  public void SomeRandomTest() { string testFileLocalPath = @"C:\path\to\my\test\file"; // Code to create an XML file with expected data goes here ... UriBuilder ub = new UriBuilder(); ub.Scheme = "file"; ub.Host = ""; ub.Path = testFileLocalPath; string request = ub.ToString(); var target = new SomethingThatReadsXml(); var details = target.ParseUserDetails(request, "dummy", "whocares"); // Compare returned user details to expected values here ... } 
+2
source

The question is not so simple, I do not agree with the opinion that this code should be designed to work and does not need testing. Personally, I would do integration tests that check the real life situation that you can run during the build or so.

To do the LOGIC test, I would decompose this thing (as you already mentioned) and make your Parser work with Stream (or its equivalent). The good thing about thread-based IO code is that you can fake data with MemoryStreams so you can test your Parser using the XML code that is written in your test. To test another thing that retrieves XML from the Internet and returns it as a Stream, it is a little more difficult to simulate, but the logic should be much simpler, you just need to test the inputs and some integration tests with invalid URL / credentials / ... the actual extraction is really a .Net implementation (which you should not test).

In the end, you will reach an outer border that you cannot fake, but the xml parser should not be like that;)

Here you can see an example: VS Magazine

+1
source

Source: https://habr.com/ru/post/979278/


All Articles