Assembly version conflicts for AutoFixture and Moq with NUnit on TeamCity 7
Asked Answered
L

2

8

I previously had all unit tests for my solution contained in a single library, and were recently split out. When located in a single assembly, all tests passed both locally and on TeamCity, but when seperated there are version conflicts.

Config:

  • Team City 7.1.5 (build 24400)
  • AutoFixture 3.20.2
  • AutoFixture.AutoMoq 3.20.2
  • Moq 4.2.1402.2112
  • NUnit 2.6.3

I have several unit test assemblies, which all reference a base test library. All test assemblies use the NuGet packages listed above.

When running tests on a dev machine (VS 2015), all tests pass successfully.

When running a team city build, the following error is thrown:

System.IO.FileLoadException : Could not load file or assembly 'Moq, Version=4.1.1308.2120, Culture=neutral, PublicKeyToken=69f491c39445e920' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040) at Ploeh.AutoFixture.AutoMoq.MockPostprocessor.Create(Object request, ISpecimenContext context)

There is no reference to Moq 4.1.1308.2120 anywhere in my solution, so I know it must be a reference from AutoFixture.

Updating AutoFixture to 3.31.3 makes no difference.

I have the following Binding Redirect in the app.config files of all test assemblies:

<dependentAssembly>
  <assemblyIdentity name="Moq" publicKeyToken="69f491c39445e920" culture="neutral" />
  <bindingRedirect oldVersion="0.0.0.0-4.2.1402.2112" newVersion="4.2.1402.2112" />
</dependentAssembly>

I cannot downgrade my version of Moq to 4.1.1308.2120 as I use features of 4.2 in my tests.

It appears to me that Team City is ignoring the redirects. I have no idea why, and having tried every combination of version for these assemblies I cannot get Team City to run the tests successfully.

Lemur answered 19/8, 2015 at 8:50 Comment(8)
How does Team City run tests? Which test runner does it use?Second
Can you reproduce the issue if you use the same test runner on a development machine?Second
I have just tried that now, all tests passed successfully :/Lemur
Is that older version of Moq hiding in the GAC on the development machine maybe? I recommend using Fuslogvw to see where it's loading from locally and then you can try it again on the TeamCity machine to see if it's doing the same thing.Druse
If I have AutoFixture.AutoMoq 3.20.1 and AutoFixture 3.20.2 I get the same error but for AutoFixture 3.20.1. This is strongly indicating that TeamCity is ignoring binding redirects.Lemur
Have you managed to find a solution to this? If not, can you post a sample solution online which uses those exact Dll versions and I can try it on my TC install?Irmairme
Can it be reproduced after clean build? I mean checking "clean all files in the checkout directory before the build" checkbox on the custom Run dialog.Psychologism
Perhaps you have a dirty nuget cache in teamcity #17697885. Try cleaning it or bypass it when you install packages.Cipher
O
2

We ran into this problem as well. We ran the assembly Fusion Logs on our build server and saw this in the error logs:

    Calling assembly : Ploeh.AutoFixture.AutoMoq, Version=3.50.2.0, Culture=neutral, PublicKeyToken=b24654c590009d4f.
===
LOG: This bind starts in default load context.
LOG: No application configuration file found.
LOG: Using host configuration file: 
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Post-policy reference: Moq, Version=4.1.1308.2120, Culture=neutral, PublicKeyToken=69f491c39445e920
LOG: GAC Lookup was unsuccessful.
LOG: Attempting download of new URL file:///D:/builds/13/s/AssessmentMigratorService.IntegrationPostbuild/bin/Debug/Moq.DLL.
LOG: Assembly download was successful. Attempting setup of file: D:\builds\13\s\AssessmentMigratorService.IntegrationPostbuild\bin\Debug\Moq.dll
LOG: Entering run-from-source setup phase.
LOG: Assembly Name is: Moq, Version=4.5.28.0, Culture=neutral, PublicKeyToken=69f491c39445e920
WRN: Comparing the assembly name resulted in the mismatch: Minor Version
ERR: The assembly reference did not match the assembly definition found.
ERR: Run-from-source setup phase failed with hr = 0x80131040.
ERR: Failed to complete setup of assembly (hr = 0x80131040). Probing terminated

So if you see this part of it

No application configuration file found.

what I think is happening is that the unit test runner host application on the build server is not seeing the application configuration file and so the assembly binding redirects are not able to apply, since they are in the app.config.

So I see 3 possible solutions/workarounds if you need to use these assemblies:

  1. Figure out why TeamCity's unit test runner on the build server cannot find the application configuration file and fix that.
  2. Use a different unit test runner on the build server.
  3. Add the binding redirects to the machine.config of the build server. That will apply globally on the entire machine, so there is no need for the redirects in the application configuration file at that point.
Offer answered 30/11, 2016 at 20:39 Comment(0)
B
2

I was embarrassed when I discovered the reason that I was seeing this error.

After 8 hours debugging I found that I had referenced TestProjectB in TestProjectA. Teamcity was set up to run any xunit against any Test*.dll that it found. So it found the TestProjectB.dll in TestProjectA's /bin/Debug folder.

But there is no TestProjectB.dll.config for TestProjectB.dll when it is in /TestProjectA/bin/Debug. Hence none of the assembly binding/redirect where being set.

I remove the project reference because it was unnecessary and updated my teamcity xunit runner to exclude dlls that don't have a matching config.

Benison answered 9/8, 2017 at 12:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.