How to use generics containing private types with Visual Studio Unit tests

I have a problem with the class I am trying to test. I have declared a private enum and I am using that in a shared vocabulary in code. This enum has no meaning outside of this class, but it is used in a private method. When I generated the code, the accessor is being written to the generic dictionary type, but when I try to use the test, it throws an invalid listing exception.

MyClass_Accessor target = new MyClass_Accessor();
Dictionary<MyClass_Accessor.MyEnum, long> dictionary = new Dictionary<MyClass_Accessor.MyEnum, long>();
dictionary.Add(MyClass_Accessor.Myenum.EnumValue, 1);
target.Method(dictionary); //Throws invalid cast exception here.

      

The exception is that the generic dictionary accessor => enum, long cannot be converted to Myclass => enum, long.

Apart from changing my working class, is there a way to test this method?

+1


a source to share


4 answers


You can use the assembly attribute InternalsVisibleTo and change your privates to internal ones. (If you can't change your private enum to an internal enum, then that won't work, but it's usually an acceptable compromise.)

Assuming you have AssemblyA being tested by AssemblyATest and the integration tested by AssemblyAIntegTest, you can paste the following into your AssemblyInfo.cs file:



using System.Runtime.CompilerServices;

// ...

[assembly: InternalsVisibleTo("AssemblyATest")]
[assembly: InternalsVisibleTo("AssemblyAIntegTest")]

      

If you sign your primary assemblies, you will also need to sign your test assemblies and provide fully qualified, cultured, and primary assembly names.

+4


a source


I must admit that the question is not clear to me. But it looks like you need to test your private method through a public caller.



Most of the time, when you are TDD, you create a public method to satisfy your test and then refactor it in private tests if you need to.

0


a source


I admit that I have not called private functions that also have private definitions the way you have, but looking at your code, you don't seem to have picked a valid value from your dictionary object.

Shouldn't the code be something like this?

target.Method(dictionary[0]); 

      

Ok, after your comment below.

The following code is taken from a test using private methods of the class (PaDeviceManager), can it be adapted to your requirements?

PaDeviceManager paDeviceManager = PaDeviceManager.Create;
PrivateObject param0 = new PrivateObject(paDeviceManager);
PaDeviceManager_Accessor target = new PaDeviceManager_Accessor(param0);
PaDeviceManager_Accessor();

      

0


a source


I readily admit that, in your context, this is a test that you might need to run, in which case jrista's answer will follow (InternalsVisibleTo).

With unit testing, however, I don't think you should usually be testing the non-public API of the classes. If this enum is private to the class and therefore only used within the class, then it should not appear in any unit test either.

The purpose of the module checks it to establish that the public (including virtual / abstract protected) API of your class is performing as expected. By including tests that rely on implementation details such as this private enum, you essentially cannot change the implementation in the future (for example, into one that may not need to be enumerated).

0


a source







All Articles