JonPSmith / EfCore.TestSupport

Tools for helping in unit testing applications that use Entity Framework Core
https://www.thereformedprogrammer.net/new-features-for-unit-testing-your-entity-framework-core-5-code/
Other
352 stars 53 forks source link

'Did not find '\bin\' in the assembly. Do you need to provide the callingAssembly parameter?' #14

Closed junkbondtrader closed 4 years ago

junkbondtrader commented 5 years ago

Hey Jon,

I'm getting the following exception from a call to CreateUniqueClassOptions: 'Did not find '\bin\' in the assembly. Do you need to provide the callingAssembly parameter?'

Stack:

TestSupport.dll!TestSupport.Helpers.TestData.GetCallingAssemblyTopLevelDir(System.Reflection.Assembly callingAssembly)
TestSupport.dll!TestSupport.Helpers.AppSettings.GetConfiguration(System.Reflection.Assembly callingAssembly, string settingsFilename)
TestSupport.dll!TestSupport.Helpers.AppSettings.GetUniqueDatabaseConnectionString(object testClass, string optionalMethodName, char seperator)
TestSupport.dll!TestSupport.EfHelpers.SqlServerHelpers.CreateOptionWithDatabaseName<Entities.ProprietaryContext>(object callingClass, bool throwOnClientServerWarning, string callingMember)
TestSupport.dll!TestSupport.EfHelpers.SqlServerHelpers.CreateUniqueClassOptions<Entities.ProprietaryContext>(object callingClass, bool throwOnClientServerWarning)

Calling code:

[Fact]
public void NoCompany()
{
      var options = this.CreateUniqueClassOptions<ProprietaryContext>();
...

I see the exception on Helpers/TestData.cs:158, but am not getting anywhere without symbols.

Any thoughts?

Thanks!

JonPSmith commented 5 years ago

I had someone else with this problem, and he was using live unit tests. Is that your case too?

The problem is that CreateUniqueClassOptions needs to access the appsetting.json file in your unit test. I have a method GetCallingAssemblyTopLevelDir which uses the calling Assembly's Location to work out the path to the appsetting.json file.

This works with Test Explorer, Resharper and in VSCode, but it doesn't work with live unit tests. I haven't got an answer to that.

junkbondtrader commented 5 years ago

I was using live unit tests, but after stopping the feature and restarting VS, I'm still seeing the error.

I typically run my tests with Ctrl+R, T but tried running from Test Explorer explicitly and still see the error.

I do have the xunit.runner.visualstudio NuGet package installed, would that play a part? I'm not particularly familiar with the VS test infrastructure but I see a testhost.x86.exe spin up, as opposed to QTAgent32.exe.

Full log:

[2/25/2019 10:13:05 AM Informational] ------ Run test started ------
[2/25/2019 10:13:06 AM Informational] [xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.4.1 (32-bit Desktop .NET 4.0.30319.42000)
[2/25/2019 10:13:07 AM Informational] [xUnit.net 00:00:00.41]   Discovering: Test
[2/25/2019 10:13:07 AM Informational] [xUnit.net 00:00:00.67]   Discovered:  Test
[2/25/2019 10:13:07 AM Informational] [xUnit.net 00:00:00.68]   Starting:    Test
[2/25/2019 10:13:08 AM Error] [xUnit.net 00:00:01.83]     ProprietaryProject.Test.ProcessorTests.PerformTaskTests.DoesNotExplode [FAIL]
[2/25/2019 10:13:08 AM Informational] [xUnit.net 00:00:01.83]       System.Exception : Did not find '\bin\' in the assembly. Do you need to provide the callingAssembly parameter?
[2/25/2019 10:13:08 AM Informational] [xUnit.net 00:00:01.83]       Stack Trace:
[2/25/2019 10:13:08 AM Informational] [xUnit.net 00:00:01.83]            at TestSupport.Helpers.TestData.GetCallingAssemblyTopLevelDir(Assembly callingAssembly)
[2/25/2019 10:13:08 AM Informational] [xUnit.net 00:00:01.83]            at TestSupport.Helpers.AppSettings.GetConfiguration(Assembly callingAssembly, String settingsFilename)
[2/25/2019 10:13:08 AM Informational] [xUnit.net 00:00:01.83]            at TestSupport.Helpers.AppSettings.GetUniqueDatabaseConnectionString(Object testClass, String optionalMethodName, Char seperator)
[2/25/2019 10:13:08 AM Informational] [xUnit.net 00:00:01.83]            at TestSupport.EfHelpers.SqlServerHelpers.CreateOptionWithDatabaseName[T](Object callingClass, Boolean throwOnClientServerWarning, String callingMember)
[2/25/2019 10:13:08 AM Informational] [xUnit.net 00:00:01.83]            at TestSupport.EfHelpers.SqlServerHelpers.CreateUniqueClassOptions[T](Object callingClass, Boolean throwOnClientServerWarning)
[2/25/2019 10:13:08 AM Informational] [xUnit.net 00:00:01.83]         Test\ProcessorTests\PerformTaskTests.cs(26,0): at ProprietaryProject.Test.ProcessorTests.PerformTaskTests.DoesNotExplode()
[2/25/2019 10:13:08 AM Informational] [xUnit.net 00:00:01.84]   Finished:    Test
[2/25/2019 10:13:08 AM Informational] [xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.4.1 (32-bit Universal Windows)
[2/25/2019 10:13:08 AM Informational] ========== Run test finished: 1 run (0:00:02.8138173) ==========
JonPSmith commented 5 years ago

The Test Explorer works for me so it's either your system or the unit test.

I suspect you are using VS2019 - yes? That could be it. Also, could you include your unit test - I just see how you call CreateUniqueClassOptions.

junkbondtrader commented 5 years ago

VS2017

I'm able to reproduce the issue in a unit test that does nothing but call CreateUniqueClassOptions.

The issue may be related to the test project being .Net Framework - I happened to try in a new .Net Core test project and everything worked as expected.

JonPSmith commented 5 years ago

Hi @junkbondtrader,

OK, I haven't tried that. I'm quite busy at the moment but I have marked it to investigate when my current contract finishes.

JonPSmith commented 5 years ago

@junkbondtrader. PS. Thanks for the coffees :)

JonPSmith commented 5 years ago

Hi @junkbondtrader,

I finally had time to look at this problem and and I added a Net472Test project to the GitHub repo.

It turns out that by default XUnit running on NET Framework creates a shadow copy of the unit tests to run. This means the code cannot get a link to the actual assembly.

The solution is to add a XUnit configuration file to turn off the shadow copy. My XUnit xunit.runner.json file provides the correct setup. NOTE: read the XUnit config docs as you need to set the file properties for it to work.

junkbondtrader commented 5 years ago

Awesome, I'll give that a go. Thanks Jon!

Fernandofat commented 4 years ago

Hi, I'm getting the same message "Unhandled exception. System.Exception: Did not find '\bin\' in the assembly. Do you need to provide the callingAssembly parameter?"

However I'm using the CompareEfWithDb in a simple a .net core 3.1 console application, I configured my EF context and debugging locally works fine, but when I compile the exe and run it on a server it gives me the mentioned error message.

Note: I'm using CompareEfWithDb method fromTestSupport.EfSchemeCompare nuget package

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Starting to check database against entities");

            using (var db = new DbContext())
            {
                var config = new CompareEfSqlConfig() { CaseComparer = StringComparer.CurrentCultureIgnoreCase };

                var comparer = new CompareEfSql(config);                

                var status = comparer.CompareEfWithDb(db);

Is there a way I can workaround this?

Any help appreciated

Thank you

JonPSmith commented 4 years ago

The exception says the CompareEfSql code triggered code that tries to find a appsetting.json file. It does that to allow you to specify the name of the connection string held in the appsetting.json file.

There is a possible workaround by using the CompareEfWithDb<T>(string configOrConnectionString, params DbContext[] dbContexts) version, with the configOrConnectionString param set to null. Please tell me if this works - think it should.

I'll reopen this issue as its possible I can improve this for CompareEfSql in a future release.

Fernandofat commented 4 years ago

Hi Jon, I will try it again soon and let you know. Thanks for the reply.

JonPSmith commented 4 years ago

Hi @Fernandofat,

I have released a new version of EfCore.TestSupport (3.1.1) where I changed the CompareEfSql code to only look for the appsetting folder if you provide a configOrConnectionString. Should slove your problem.