0

Context. I have interface IVehicle, class VehiclesFactory and private class Vehicle nested in the VehiclesFactory. Thus all code except the VehiclesFactory kwnows nothing about any implementations of the IVehicle.

Question. How should I unit test the Vehicle? And should I do it at all?

Assumption 1. I can make the Vehicle public. However this will allow the all code to write new VehiclesFactory.Vehicle(...) which I try to avoid.

Assumption 2. I can make a new public method in the VehiclesFactory, e. g., IVehicle ForUnitTests_Vehicle(...) which just calls the Vehicle constructor and passes its arguments to that constructor (allowing a unit test to supply necessary mocks). However this will allow the all code to call this strange method.

Assumption 3. Factories is a plague; use the new operator everywhere. However this will couple my code more tightly.

Hoborg
  • 891
  • 12
  • 21
  • 1
    my first question would be what exactly is the vehicles factory doing and how is it being used? If the `Vehicle` class is private within the `VehiclesFactory` you would not be able to return a new instance of `Vehicle`. Unit tests should test the public API if your system so you should be testing the factory. – Aaron Roberts Sep 30 '17 at 14:12
  • @AaronRoberts Q: what exactly is the vehicles factory doing and how is it being used? A: E. g., the VehiclesFactory calls some other services, assembles a VehiclesFactory.Vehicle instance and tunes it a little. The other code interacts with that instance calling the method Drive which behaviour depends on the vehicle parts. Thus I'd like to test the Drive method; I would supply different vehicle parts and method arguments and verify the result. – Hoborg Sep 30 '17 at 16:48
  • 1
    I think I understand, but if there is no way to interact with the vehicle class except for within the factory, I'm not sure if testing the vehicle class directly is or considered a good idea. If the drive method executes some other dependency code you could verify that the dependent code got called properly. Without a code sample its hard to tell – Aaron Roberts Sep 30 '17 at 16:56
  • 1
    duplicate of [this question](https://stackoverflow.com/questions/9122708/unit-testing-private-methods-in-c-sharp) you can see there an interesting discussion +suggestion to use PrivateObject – Ami Oct 01 '17 at 09:21

1 Answers1

1

How should I unit test the Vehicle?

You can use reflection to create an instance of Vehicle class in your test project or make your Vehicle class internal and use InternalsVisibleToAttribute attribute to make it visible to your test project. Though switching from private to internal will make your class visible to all the code in the same project, so I'm not sure if it's acceptable for you.

And should I do it at all?

Up to you, if it contains application critical logic probably you should test it.

Maksym Strukov
  • 2,679
  • 1
  • 13
  • 17
  • Thanks for the answer. I'll try this approach a little to reveal other issues it may entail. I'm going to retrieve a SUT instance via something like: var vehicle = (IVehicle)Activator.CreateInstace(Type.GetType("VehiclesFactory.Vehicle")). And then I'll call its public interface methods. – Hoborg Oct 04 '17 at 17:34
  • Currently I'm satisfied with the helper method which utilizes the Activator.CreateInstance method. The helper method has an access to at least one visible type of the assembly containing the target type (e. g., VehiclesFactory.Vehicle). Also it unwinds TargetInvocationException (if any) and rethrow the "real" exception. Obviously this approach breaks compile-time connection between the tested module and the test. – Hoborg Dec 19 '17 at 19:10