Take the 2-minute tour ×
SharePoint Stack Exchange is a question and answer site for SharePoint enthusiasts. It's 100% free, no registration required.

I have a SharePoint 2010 project in VS 2010, and I'm trying to develop some unit tests to test my code.

I have followed all of the instructions here to prepare my VS2010 environment to re-target the test project to .NET 3.5.

I generated a new test project by right-clicking in my SharePoint code, selecting "Create Unit Tests" and selecting the methods I wanted to test. I re-targeted the test project to .NET 3.5, enabled 64 bit testing, etc.

Now, when I try to run the tests, they fail with an error:

Warning: Test Run deployment issue: Failed to get the file for deployment item 'My.CodeToBeTested.dll' specified by the test 'My.TestProject.MyTestClass.MyTestMethod': System.IO.FileNotFoundException: Could not find file 'C:\Path\To\My\Project\My.CodeToBeTested.dll'.

It seems as though VS is looking for the .dll directly in the root folder of the project, instead of in the project\bin\debug folder.

Now, if I re-target the test project back to .NET 4.0, it deploys fine, and I can run tests that do not specifically use the SharePoint object model. But, obviously can't run tests that do use the SharePoint object model. So that's no good for me.

Also, I am unable to debug the tests when the test project is targeted to 3.5. It starts to run, and then kicks me out of debug mode and stops running, with no explanation.

Anyone know why targeting the test project to .NET 3.5 breaks VS's ability to locate the .dll? Or is preventing me from debugging?

EDIT 3/21/13

Ok, I demolished the test project and completely rebuilt it. I'm no longer getting the error where it seems that VS can't find my assembly to be tested. Instead, this is what's happening:

Whether I run the tests or try to debug them, all tests fail (and if debugging, no breakpoints are hit). When I look at the error message for why the tests fail, they all fail for the following reason:

MyTestProject.MyTestClass.MyTestMethod threw an exception: System.BadImageFormatException: Could not load file or assembly 'My.Assembly.ToBeTested_Accessor', Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded.

Now, keep in mind I have re-targeted the test project to .NET 3.5, and cleaned and rebuilt it several times. I have watched the My.Assembly.ToBeTested_Accessor.dll and .pdb files get removed from the /bin/Debug directory on cleaning the project, and manually deleted them from the /obj/Debug directory, and watched them both reappear upon rebuild - which is supposedly happening under .NET 3.5 - and yet I keep getting the same error.

I see a directory called Test References with a file called My.Assembly.ToBeTested.accessor in it, but all it has in that file is two lines:

My.Assembly.ToBeTested.dll
Desktop

and I can't see any way in the file properties to specifically re-target that file to .NET 3.5.

Does anyone know what is going on here, or how I can get these tests to run?

I'm starting to get a wee bit frustrated with this thing.

share|improve this question

1 Answer 1

up vote 1 down vote accepted

Why yes, Dylan, I do know what's going on here, and can help you get those tests to run.

First of all, the reason you have that accessor assembly in the first place is that you decided to test some private methods. There are various arguments out there about why you should or should not be testing private methods. Without addressing that debate here, let's keep trying to help you get your tests working.

If you look on MSDN, you will see that accessors have been deprecated in VS2010. You might also see the availability of a command line tool called Publicize.exe that will generate an assembly that wraps all your private methods in public ones that will enable you to test them.

What is likely happening is that behind the scenes, VS2010 is using Publicize.exe to automatically generate that accessor assembly for you. Since the MS unit testing framework originally targets .NET 4.0 (remember, you had to jump through some hoops to re-target your test project to 3.5), Publicize.exe probably operates as .NET 4.0, which is why you continually get that "built by a newer runtime" error.

Fortunately, there is a way around this.

The way to do it is to abandon trying to use the accessor assembly and wrapper class generated by Publicize.exe, and go straight for the class you want to test. You might notice at the beginning of each test method, a line something like this:

MyClassToTest_Accessor target = new MyClassToTest_Accessor();

This should be changed to:

MyClassToTest target = new MyClassToTest();

We're off to a good start, but wait -- now we get errors when we try to call the methods we're trying to test, because they are private! We can get around this by using a PrivateObject object. So the next step is to create a PrivateObject that accesses the class you want to test, like this:

MyClassToTest target = new MyClassToTest();
PrivateObject accessor = new PrivateObject(target);

We're almost there. The final step is to now call the method we are trying to test using the new accessor object instead of the target object. So, we will need to change the lines that read something like:

SomeType actual;
actual = target.MyMethodToTest(param1, param2);

to:

SomeType actual;
actual = (SomeType)accessor.Invoke("MyMethodToTest", new object[] { param1, param2 } );

Just to make things clear, PrivateObject.Invoke will return an Object type, so you will need to cast it back to the original type you were expecting as a return from the method you are calling.

Voila! You are testing private methods while targeting .NET 3.5 and accessing the SharePoint 2010 object model!

Problem solved.

EDIT:

Oh, forgot to link to this helpful post on StackOverflow.

share|improve this answer
    
+1 for detail, I think, but more so for writing to yourself in the second person :D –  James Love Mar 22 '13 at 20:02

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.