I would say there are many valid reasons for using reflection to easy unit testing. To quote https://github.com/kbilsted/StatePrinter
the problems with manual unit testing
It is laborious.
When I type and re-type over and over again: Assert.This, Assert.That, ... can't help but wonder why the computer cannot automate this stuff for me. All that needless typing takes time and drains my energy.
When using Stateprinter, the asserts are generated for you whenever there is a mismatch between expected and actual values.
Code and test gets out of sync
When the code changes, say by adding a field to a class, you need to add asserts in some of your tests. Locating where, though, is an entirely manual process. On larger project where no one has the full overview of all classes, the needed changes are not performed in all the places it should.
A similar situation arises when merging code from one branch to another. Say you merge a bug fix or feature from a release branch to the development branch, what I observe over and over again is that the code gets merged, all the tests are run and then the merge is committed. People forget to revisit and double check the entire test suite to figure out there are tests existing on the development branch and not on the branch from where the merge occured, an adjust these accordingly.
When using Stateprinter, object graphs are compared rather than single fields. Thus, when a new field is created, all relevant tests fail. You can adjust the printing to specific fields, but you loose the ability to automatically detect changes in the graph.
Poor readability I
You come a long way with good naming of test classes, test methods and standard naming of test elements. However, no naming convention can make up for the visual clutter asserts creates. Further clutter is added when indexes are used to pick out elements from lists or dictionaries. And don't get me started when combining this with for, foreach loops or LINQ expressions.
When using StatePrinter, object graphs are compared rather than single fields. Thus there is no need for logic in the test to pick out data.
Poor readability II
When I read tests like the below. Think about what is it that is really important here
Assert.IsNotNull(result, "result");
Assert.IsNotNull(result.VersionData, "Version data");
CollectionAssert.IsNotEmpty(result.VersionData)
var adjustmentAccountsInfoData = result.VersionData[0].AdjustmentAccountsInfo;
Assert.IsFalse(adjustmentAccountsInfoData.IsContractAssociatedWithAScheme);
Assert.AreEqual(RiskGroupStatus.High, adjustmentAccountsInfoData.Status);
Assert.That(adjustmentAccountsInfoData.RiskGroupModel, Is.EqualTo(RiskGroupModel.Flexible));
Assert.AreEqual("b", adjustmentAccountsInfoData.PriceModel);
Assert.IsTrue(adjustmentAccountsInfoData.IsManual);
when distilled really what we are trying to express is
adjustmentAccountsInfoData.IsContractAssociatedWithAScheme = false
adjustmentAccountsInfoData.Status = RiskGroupStatus.High
adjustmentAccountsInfoData.RiskGroupModel = RiskGroupModel.Flexible
adjustmentAccountsInfoData.PriceModel = "b"
adjustmentAccountsInfoData.IsManual = true
Poor convincibility
When business objects grow large in number of fields, the opposite holds true for the convincibility of the tests. Are all fields covered? Are fields erroneously compared multiple times? Or against the wrong fields? You know the pain when you have to do 25 asserts on an object, and painstakingly ensure that correct fields are checked against correct fields. And then the reviewer has to go through the same exercise. Why isn't this automated?
When using StatePrinter, object graphs are compared rather than single fields. You know all fields are covered, as all fields are printed.