Reputation: 1033
I have the following code, that I'm trying to Unit test:
class ConfigFile
{
private XmlDocument configData;
public ConfigFile()
{
configData = new XmlDocument();
}
public void loadConfigFile(string filename)
{
}
}
the loadConfigFile method is void, so I need to check the configData field to verify that the data in there is correct. To Do this, I'm trying to use the InternalsVisibleTo attribute - I've signed the unit test DLL, and generated the Public Key, so I now have:
[assembly: InternalsVisibleTo("ConfigTests, PublicKey=<PUBLICKEYVALUE>")]
private XmlDocument configData;
The unit test still doesnt want to access the private field:
[TestMethod()]
public void LoadConfigFileTest()
{
ConfigFile target = new ConfigFile();
string filename = @"Config.xml";
target.loadConfigFile(filename);
Assert.AreEqual("<config></config>",target.configData.OuterXml);
}
At the Assert.AreEqual("",target.configData.OuterXml); line, I get the following error:
'ConfigTests.ConfigFile' does not contain a definition for 'configData' and no
extension method 'configData' accepting a first argument of type
'ConfigTests.ConfigFile' could be found (are you missing a using directive or
an assembly reference?)
I though the InternalsVisibleTo attribute is supposed to allow Unit tests to access a private field... or am I missing something?
Upvotes: 6
Views: 9432
Reputation: 1
Use a publicizer such as BepInEx.AssemblyPublicizer.MSBuild or Krafs.Publicizer.
They allow full access to the target reference as if everything is public.
They can also create "stripped" versions of assemblies similar to a ref library.
Upvotes: 0
Reputation: 56984
InternalsVisibleTo enables you to access internal members (not private) from another assembly.
If you want to test a private method, then you should ask yourself if that method should be really private ?
Why do you want to test a private method ? Doesn't it make more sense to test the public method that calls the private method ? With your private method, you're hiding some implementation details and typically, that's something you don't want / need to test directly. You want to test if your public 'contracts' work as expected. So, if everything is OK, you'll test your private method indirectly by testing the public method that uses / calls the private method.
Upvotes: 6
Reputation: 17145
InternalsVisibleTo
makes all internal
children visible to the given assembly.
If you want to make a private
method visible to another assembly that's essentially a paradox. It means breaking the foundations of OOD.
Unit testing is supposed to test the public API of a black box. i.e. your classes should be designed in such way that you only need to test their public methods.
Make your method public
.
If it mustn't be public
, then you can make it protected internal
so that it can be accessible by using InternalsVisibleTo
Making it protected internal
poses a security threat which must be addressed either by sealing the class and all its container classes or by standard security assessment.
If this didn't help, don't test it because it's not a concern for unit tests. Test a public method which uses this.
If something is private, it literally (in every programming or spoken language) means no one else cares about it!
Upvotes: 4
Reputation: 1
Change the access to internal protected and then seal the class. This way ONLY the friend assembly can access it.
Upvotes: 0
Reputation: 2280
I suppose your class ConfigFile has other public properties/methods intended for reading the config values. For this reason the configData
is private. In such case you can apply a black box tests to it (i.e. make assertions on these values rather than on entire XmlDocument)
Upvotes: 0