Castle Windsor - FileNotFoundException in Unit Tests - c#

I’ve inherited an ASP.Net web application comprising of VB.Net projects. I’ve added a C# project to the solution, which references several of the VB.Net projects.
The application uses Castle Windsor as a DI container and dependencies are registered in one of the VB.Net projects.
In that VB.Net project. to avoid circular references, I use the “FromAssemblyNamed”, method to register the dependencies that are defined in my C# project:
container.Register(Classes.FromAssemblyNamed("x.y.z.TLBusinessLayerV2").BasedOn(Of IService).WithService.FromInterface().Configure(Function(c) c.LifeStyle.Transient))
This is working fine when I run the application.
However, there is an existing Unit Test project. In that I have added a reference to my C# assembly.
When I run all of the tests, some of the tests fail when they hit the code above with the following exception:
System.IO.FileNotFoundException: Could not load file or assembly x.y.z.TLBusinessLayerV2' or one of its dependencies. The system cannot find the file specified.
All of the assemblies referenced by the C# Assembly are also referenced by the Unit Test project.
The Target CPU for the VB.Net project, C# project and Unit Test project are all set to x86.
If I then run one of the failed tests individually, the test passes.
Q. Why are the Tests failing when I run them all?
Any help much appreciated.

The solution to this issue is to add a dummy class to the Unit Test project, that references a class in the assembly (loaded in "Classes.FromAssemblyNamed"). Something like:
Public Class DummyDependencies
Private Xyz As Object = GetType(<name of a class in target assembly>)
End Class
This appears to enforce the reference to the assembly.

Related

Net Core: Find Application Assembly Location from Integration Test

We have a API Real Application which is running following code to get the Assembly Directory.
Assembly.GetEntryAssembly().Location
Result:
C:\\OriginalApplicationAPI\\bin\\Debug\\netcoreapp2.2
Now we are running an Integration Xunit project, which is running the Startup, appsettings, etc from the original project.
Running this code from the Integration test project renders,
C:\\Users\\..\\.nuget\\packages\\microsoft.testplatform.testhost\\15.9.0\\lib\\netstandard1.5"
How do I refer to the OriginalApplicationAPI Assembly Location from test project? Is it by namespace or project reference?
Thanks,
You will need to know of a Type that is in the assembly.
Let's say App.MyClass is defined in the assembly. You can use reflection to get the location of the assembly containing that type:
Assembly.GetAssembly(typeof(App.MyClass)).Location.
You can't do it using a namespace as a namespace can exist across multiple assemblies.
Or utilize
Assembly.GetExecutingAssembly().Location

Unit Testing UWP app that references unmanaged dll causes System.TypeLoadException

Trying to Unit Test a UWP app that has a dependency on a .winmd file.
If the unit test calls a method in the app that makes a call on a class in the unmanaged dll then I get a System.TypeLoadException. I've tried referencing different .winmd files and using either MSTest framework or xunit but always get the same error. Other unit tests work fine.
Issue can be reproduced..
Create a new solution with a Universal Windows test project.
Add the required nuget packages for xunit(xunit, xunit.runner.visualstudio) or MSTest(MSTest.TestFramework, MSTest.TestAdapter) - it fails with either framework.
Add a reference to an unmanaged dll. I used SamplesNative.winmd that can be found as part
of the Windows UI Dev Labs -
https://github.com/Microsoft/WindowsUIDevLabs.
Create a unit test that calls on the unmanaged dll. Using SamplesNative above I added:
var helper = new DeviceLostHelper();
Run unit test and it should fail with - System.TypeLoadException: Requested Windows Runtime type 'SamplesNative.DeviceLostHelper' is not registered. ---> System.Runtime.InteropServices.COMException: Class not registered
Any help would be great. Thanks.
After further testing and help from Microsoft here:
https://social.msdn.microsoft.com/Forums/vstudio/en-US/68b9ee55-cd7a-4334-952a-a7ecfff4c6ca/unit-testing-uwp-app-that-references-unmanaged-dll-causes-systemtypeloadexception?forum=vsunittest
I have determined that the issue is relating to Resharper. If I disable Resharper and run the unit tests using MsTest Framework and in Test Explorer than the tests work normally.
I achieved this by un-toggling the Enable MSTest support checkbox in Resharper Options->Tools->Unit Testing->MsTest.

NDepend TypeInitializationExceptions when Testing with NUnit

So I'm trying to set up a project using the NDepend API for some metrics on my code (Which works nicely), however, when I attempt to run a testing framework (NUnit) over it, I'm getting TypeInitializationExceptions thrown.
Here is some code to reproduce the errors I'm getting:
Create a class library project, and reference the NDepend API dll at $NDependInstallPath$\lib\NDependAPI, setting copy local to false. Create a class as follows:
public class NDependProjectLoader
{
public void LoadAnNDependProject()
{
var provider = new NDependServicesProvider();
}
}
Create a second class library project in the solution that will be your Test class. Reference NUnit and the project you created that references the NDependAPI
[TestFixture]
public class NDependProjectLoader_Tests
{
[Test]
public void I_can_load_an_depend_project()
{
new NDependProjectLoader().LoadAnNDependProject();
}
}
Build, and run the test using your test runner of choice (I've tried Resharper's test runner and the NUnit GUI).
You will get a TypeInitializationException on the line var provider = new NDependServicesProvider();
Looking inside that TypeInitializationException shows that the root exception's message is:
"{"Could not load file or assembly 'NDepend.Platform.DotNet' or one of its dependencies. The system cannot find the file specified.":"NDepend.Platform.DotNet"}".
Adding the AssemblyResolverHelper from the NDepend.PowerTools sample project and calling it as described in the getting started guide doesn't change the behaviour.
I /assume/ that the problem is related to this statement in the NDepend API getting started guide at http://www.ndepend.com/api/NDepend.API_gettingstarted.html
"The program executable assembly must be generated into $NDependInstallPath$\"
In the case where the code is started from a test runner the executable will not be in the ndepend install path.
Calling NDependProjectLoader.LoadAnNDependProject() from a console application whose .exe is generated in $NDependInstallPath$\lib\ (note that the .exe seems to need to be generated in the \lib\ subfolder not in $NDependInstallPath$\ as stated in the getting started guide) does not produce the exception, which further points to this being the cause.
So, the question is, how does one work with the NDepend API from anything other than a console application? For example, here I want to do so from a test runner. Another obvious candidate is an IIS application. Am I missing something obvious?
Indeed the problem comes from assembly resolution.
You must tell the CLR where to find NDepend assemblies (i.e in the dir $NDependInstallPath$\Lib)
You have 2 choices to do this. Suppose $NDependInstallPath$ is "C:\NDepend" just for example:
Either edit AssemblyResolverHelper to resolve assemblies in "C:\NDepend\Lib"
Either create a App.Config file for your exe, add a <probing> element that refers to "C:\NDepend\Lib". When the CLR won't resolve an assembly, then it'll look at dir in such element

Microsoft.Win32.ShimRegistryKey not working on build machine

I Have lots of unit tests where I shim the Microsoft.Win32.RegistryKey using Microsoft Fakes. When I run the build on my local machine the unit test passed. But if I run it on build machine the unit test fails with the following error for these tests.
System.TypeLoadException: Could not load type
'Microsoft.Win32.Fakes.ShimRegistryKey' from assembly
'mscorlib.4.0.0.0.Fakes, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=0ae41878053f6703'.
The curious thing is that both my local machine and build machine are 64-bit and the unit test project are targeting AnyCPU. Is there some configuration could be missing on the build machine?
I just has a similar issue when using Shims in multiple separate Unit test projects. Apparently the generated shims can overwrite each over or something like that.
Here's the instructions I followed to fix it:
Scroll to the middle of this page: https://msdn.microsoft.com/en-us/library/hh708916.aspx
It's under the heading of optimise build times, but use it to fix your problem too.
Because such assemblies rarely change on your machine, you can reuse the generated Fakes assemblies in other projects.
From your unit test projects, you can simply take a reference to the compiled Fakes assemblies that are placed under the FakesAssemblies in the project folder.
Create a new Class Library with the .NET runtime version matching
your test projects. Let’s call it Fakes.Prebuild. Remove the
class1.cs file from the project, not needed.
Add reference to all the System and third-party assemblies you need
Fakes for. and generate the fakes, edit the .fakes file if you like,
and build to generate the fake assemblies.
From your Unit Test projects Just make sure that you have a reference
to the Fakes runtime DLL: C:\Program Files\Microsoft Visual Studio
12.0\Common7\IDE\PublicAssemblies\Microsoft.QualityTools.Testing.Fakes.dll
Then for each assembly that you have created Fakes for, add a
reference to the corresponding DLL file in the
Fakes.Prebuild\FakesAssemblies folder of your project. (This folder
get created when you compile)
To confirm You will need to add the reference by Browsing to the
generated fake assembly..

nunit and log4net

I am unable to test my log4net library using nunit. I read the search results returned by Google but could not understand them.
This is the error that I am getting.
System.IO.FileNotFoundException : Could not load file or assembly
'log4net, Version=1.2.10.0, Culture=neutral,
PublicKeyToken=692fbea5521e1304' or one of its dependencies. The
system cannot find the file specified.
In my nunit test project I have added the reference to correct log4net dll that rest of the projects are using and added the configuration files but no luck.
My Console application and test web application that use the log4net libaray are working correctly.
I seem to only have problem with log4net nunit test project.
How can I get started with simple nunit test involving log4net library.
You should be accepting an ILog in whatever you're trying to test. Then you should mock it and pass it to whatever you're attempting to test. The version of log4net shouldn't matter at all. Your tests shouldn't even know log4net exists.
Using Rhinomocks, this would be:
MockRepository mocks = new MockRepository();
ILog mockLog = mocks.DynamicMock<ILog>();
Alternatively you could go with a stub:
ILog mockLog = MockRepository.GenerateStub<ILog>();
Check that Version of log4net.dll is same for your tests project and for projects which are referenced by tests (btw latest version of log4net is 1.2.11.0). Also verify that Copy Local is set to true.
If you are involving log4net library, then this is probably integration test, not unit test.
Double check the run-time log4net.dll file you have included. It looks like it could not match the .NET run-time CLR of your project. Check the target NET version of your app (Project -> Properties), and make sure it matches the target version of log4net.dll. Note version 1.2.11 of log4net includes binaries up to version 4.0, and also note client-profile versions are distinct than full versions, requiring their own specific dll files.

Categories

Resources