问题
My build server uses MSBuild to build my application. Our unit tests require access to some private members for testing, so we use the built in private accessors. Visual Studio has no problem with it, but when we push our code to the build server we get the error:
MyTest.cs (96,13): errorCS0246: The type or namespace name 'My_Accessor' could not be found (are you missing a using directive or an assembly reference?)
Why is it that MSBuild ignores the private accessors and how can I fix it?
We use NUnit for our testing framework and CruiseControl.Net for our continuous integration server.
EDIT: As per the comment, here is some test code for the base class for a repository pattern class.
MockRepository mocks = new MockRepository();
IDataContextWrapper wrapper = mocks.DynamicMock<IDataContextWrapper>();
Repository_Accessor target = new Repository_Accessor(wrapper);
Assert.AreEqual(wrapper, target._DataContext);
This code simply verifies that the member variables _DataContext is set to the mocked wrapper. It fails when building with MSBuild on my build server.
回答1:
It seems like your build setup is not generating the private accessor assembly. As a result, you're getting that missing using directive or assembly reference error. You can look at Publicize tool to generate the private accessor during your build process. It is mentioned in there that
The generated assembly is also known as a private accessor. You can also generate private accessors from the IDE, but you might use publicize.exe instead in Automation, scripting, and build scenarios.
I use private accessors as well in some of the tests and use TFS TeamBuild and MSTest. Private accessor gets generated during builds. I did not have to do anything manually.
回答2:
Do you by chance have [assembly:InternalsVisibleTo] set correctly locally but incorrectly on your build system?
(Also, Assert.AreSame() might be more appropriate).
回答3:
You mentioned private accessors so I assumed that you are using Reflection to expose some private members for unit testing?
If that is the case, then you must understand that peeking into private members requires a certain rights to be granted. Or else, a rogue .NET program could tamper with anything it wants with whatever assemblies it wants.
Are you sure that the user Cruise Control is running under and subsequently, the build runner and test runner CruiseControl launches are running under an account that is given "ReflectionPermission" or "Full trust" from the .NET runtime?
Places to look/google for are the machine.config settings on the build server, Cruise Control's own web.config (not sure if it has one since I've not used CC for a long time) and lastly (and least probably), the app.config file of both the test runner and the application under test itself.
Otherwise, I suggest you use the Publicize tool as @Mehmet Aras suggested.
回答4:
As good as Mehmet's answer was, I'm afraid the only way I could get this to work was to install visual studio. Once this was installed, msbuild started to produce the accessors for me. Not an ideal solution but at least I can move on.
来源:https://stackoverflow.com/questions/1320039/private-accessor-dont-build-when-using-msbuild