Net Core: Find Application Assembly Location from Integration Test - c#

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

Related

Castle Windsor - FileNotFoundException in Unit Tests

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.

C# DllImport Inconsistency

I am testing that I am using the correct dll interface for a ThirdParty.dll but using a mocked unmanaged dll in some unit tests. The ThirdParty.dll is imported using DllImport("ThirdParty.dll") inside the production code. The mock dll is placed in the same directory as the NUnit test code, the working directory of the command line set to the same directory as the Test Dll and mock dll, and then NUnit is called with a full path.
Example:
TestDirectory contains:
Test.dll
nunit.framework.dll
pnunit.framework.dll
ThirdParty.dll
and some other dependencies.
and the following is called:
C:\TestDirectory>ProgFiles\NUnit\nunit-console-x86.exe Test.dll /config:Release /framework:net-4.0
On our development machines the mock version of ThirdParty.dll is picked up fine and our tests pass but when we put the same code and directory structure on the customer computer it picks up the real installed version of the dll instead, which we also have installed on our dev machines but gets blocked by the mock one during unit tests.
I'm aware of the Search Order used by Windows, but I think that in both instances the DLL should be found in step 1 "The directory from which the application loaded.". I'm also aware of picking up the same name DLL if it is in memory, but I believe this applies if it is in the same process memory, which it should not be.
Does anyone have any ideas on what I could check or what might be causing this?
Thanks
The search order for dynamic link libraries can be found here. It's always the same, but it does depend on operating system settings, so with two different machines with different settings, you may get different results.
Use the fusion log viewer to get a more detailed view into how your assembly is being found. The viewer will list all paths your application is searching to load an assembly and where they were found. This always give me an answer when I have unexpected DLL dependency problems.

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..

Global assembly cache and dlls

We have a class library we ve created using C# and .NET 3.5. The highest leveled namespace in the namespace hierarchy of that class library is say Abc.
When we use the output dll of the class library (Abc.MyLibrary.dll) in a test application in another test machine, it gives a compile time error saying Abc.dll is missing.
But when we build the class library within that test machine, then it gives no error and compiles.
Is this something related to GAC or is there any other reason for this conflicting situation?
Thanks in advance
It depends on your exact project settings, but Visual Studio might install the Assembly to the Global Assembly Cache.
Use Gacutil.exe AssemblyName from the Visual Studio Command line to check if it is installed or not.

Namespace in Referenced Project Present in Autocomplete Before Building, but Causes Compile Error After Building

I have a class library project which uses a namespace (e.g., "Cosmos.Creator.Util"). I then create a solution and windows forms application to test the library. From the windows form application, I add a reference to the library. So now I have two projects open in visual studio, a class library and a windows forms project. The forms project references the library.
When I edit my form's code, code autocompletion works correctly for the namespace that I use in the library. E.g., if I type "using Cosmos." I get autocomplete options like "Creator". But now if I build my solution, all of the "Cosmos" are red-underlined with the compile error: "The type or namespace name "Cosmos" could not be found (are you missing a using directive or an assembly reference?)".
For the purposes of the form application test, I placed my library code into a folder CosmosFormExample\Cosmos. When I check the reference from the form application, the reference is to CosmosFormExample\Cosmos\bin\Debug\Cosmos.dll, so that looks okay. I looked at the GUID referenced in the solution file and it matches the GUID of the project file Cosmos.csproj.
What has happened? How has the build caused my forms application to forget about the Cosmos namespace, despite the fact that it is still referencing the library project? Thanks much in advance.
Are you using VS2010 & .NET 4? If so you're probably using .NET 4 Client Profile instead of full fledged .NET 4. Go to project properties and check your Target Framework.
for more info: http://msdn.microsoft.com/en-us/library/cc656912.aspx
you need to check the framework you are using and the framework yout library was compiled for...

Categories

Resources