In my solution, I am writing a unit test with NUnit that uses Mono.Cecil.
The concept is pretty simple: I have three assemblies ASource, ATest, ATestUtils.
- ASource: Contains a class "MyClass" that I want to test. (The assembly references other assemblies.)
- ATest: Contains the unit test that tests "MyClass" in ASource.
- ATestUtils: References Mono.Cecil an provides utility methods to - I keep it simple to give an example - returns all the property names of an input type (I know, I do not need Mono.Cecil to do that, but it is just an example here).
In my ATestUtils, I load the assembly ASource like so:
// In ATestUtils
public static IEnumerable<PropertyDefinition> GetPropertiesFromType(Type typeOfClass)
{
var ass = AssemblyDefinition.ReadAssembly(typeOfClass.Assembly.Location);
var refs = ass.MainModule.ImportReference(typeOfClass);
var typeDef = refs.Resolve();
return typeDef.Properties;
}
When I run my unit test "MyUnitTest" using that method from ATestUtils on my local machine (debug and release), it works fine. When it is executed on my jenkins , it gives the following Error:
Error : ATest.MyUnitTestClass.MyUnitTest
Mono.Cecil.AssemblyResolutionException : Failed to resolve assembly: 'ASource, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'
bei Mono.Cecil.BaseAssemblyResolver.Resolve(AssemblyNameReference name, ReaderParameters parameters) in C:\src\cecil\Mono.Cecil\BaseAssemblyResolver.cs:Zeile 122.
bei Mono.Cecil.BaseAssemblyResolver.Resolve(AssemblyNameReference name) in C:\src\cecil\Mono.Cecil\BaseAssemblyResolver.cs:Zeile 117.
bei Mono.Cecil.DefaultAssemblyResolver.Resolve(AssemblyNameReference name) in C:\src\cecil\Mono.Cecil\DefaultAssemblyResolver.cs:Zeile 33.
bei Mono.Cecil.MetadataResolver.Resolve(TypeReference type) in C:\src\cecil\Mono.Cecil\MetadataResolver.cs:Zeile 110.
bei Mono.Cecil.ModuleDefinition.Resolve(TypeReference type) in C:\src\cecil\Mono.Cecil\ModuleDefinition.cs:Zeile 748.
bei Mono.Cecil.TypeReference.Resolve() in C:\src\cecil\Mono.Cecil\TypeReference.cs:Zeile 280.
bei ATestUtils.TestTools.GetPropertiesFromType(Type typeOfClass) in D:\Hudson\workspace\MyBranchName\MyProject\ATestUtils\TestTools.cs:Zeile 47.
bei ATest.MyUnitTestClass.MyUnitTest()
I checked the path "typeOfClass.Assembly.Location" on my jenkins and I am very certain that the dll was created and exists during the test step of my jenkins.
I have a feeling that I have not yet understood how to correctly load assemblies with Mono.Cecil. Is it possible that my project ATest cannot be loaded correctly on the jenkins because it has dependencies to other assemblies? Do I have to load them "somehow" as well? If so how? And why is it working on my local machine then?
My environment:
Visual Studio 2022 v17.6.3
Mono.Cecil v0.11.5
NUnit v3.13.3
NUnit3TestAdapter v4.5.0.
Jenkins v2.401.1, using a jenkins script (pipeline syntax), bs.Windows10.amd64, the test step executes a powershell script that executes the unit tests using NUnit.Console 3.12.0 and opencover.4.7.1221
I am grateful for any help. If more information is needed to answer the question, I will be happy to provide it.
You must describe the example in more detail, please. As far as I understand, you pass a type from the
ASourceassembly to theGetPropertiesFromTypemethod. I assume the type is not NULL. In this casetypeOfClass.Assembly.Locationshould also give you the correct location and the assembly should be loaded. Now I don't understand why you import the passed type again? You know that this type is included in the assembly. I would therefore write the following:Also, I assume that you meant an
IEnumerable<PropertyDefinition>as the return type of theGetPropertiesFromTypemethod?If my assumptions are correct and the assembly
ASourceis configured as a project reference inATest, my unit test will run successfully.Is your assembly referenced in your Unit Test assembly? And are all assemblies referenced by
ASourcealso copied so thatATestcan find them?