Getting the desired / correct assembly path while unit testing with NUnit
Asked Answered
O

4

12

I just started experimenting moq for unit testing my modules.

Actually, the class for which I have to write an unit test uses

Assembly.GetExecutingAssembly().Location internally to determine a path.

But, this doesn't work while writing unit tests because, the path of the executing assembly is different (the path of the unit testing assembly is taken)

AppData\\Local\\Temp\\3ylnx32t.ukg\\TestApplication.Test\\assembly\\dl3\\aeb938e6\\f3664631_d982ce01.

I tried, disabling shadow copying.

AppDomainSetup appDomain= new AppDomainSetup{ShadowCopyFiles = "false",};
appDomain.ShadowCopyFiles=false.ToString();

still, it doesn't work!

Any suggestions are appreciated. Thanks in advance.

Oloroso answered 17/7, 2013 at 11:32 Comment(2)
I had some problems with assembly paths during unit testing, as well. Probably it helps, take a look at #17314331Rodge
@OP I doubt that this is a problem with moq. What testing framework are you using? NUnit, for example runs the tests in a separate AppDomain with ShadowCopy enabled.Hower
O
3

Finally, I accomplished this through this way:

I used NUnit Framework and disabled Shadow copying in NUnit. Created a copy of my configuration file in that directory where the unit testing library is invoked.

So, whenever my unit test is invoked (say from path 'A'), my application doesn't complain that there is no configuration file in that location since i put my configuration file in path 'A'.

(ps: The reason why I get the assembly location is to be able to find my configuration file in that location)

[The whole idea is this: with shadow copying, the assembly path is dynamic. disable it and the assembly path is static]

Oloroso answered 6/8, 2013 at 9:21 Comment(4)
How did you turn off the ShadowCopy? I've tried all sorts of code and nothing seems to turn it off. Can you give us a sample?Spirometer
Actually, I disabled shadow copying in NUnit. Go to Tools->Settings and uncheck the Enable Shadow Copy check box. That should do the trick.Oloroso
Ah. I thought that you had removed it from the app. I've been trying to remove it from my desktop app, and nothing seems to work.Spirometer
@Erick: Yup, thats true. I tried to disable it but could not.Oloroso
P
19

You can use TestContext.CurrentContext.TestDirectory as mentioned by Charlie Poole from NUnit here.

Reference: https://mcmap.net/q/302332/-trouble-with-nunit-when-determining-the-assembly-39-s-directory

Phlyctena answered 15/3, 2015 at 4:53 Comment(0)
A
10

Perhaps not an exact answer to your question, but personally, I wouldn't even try to get the actual value of Assembly.GetExecutingAssembly().Location during a unit test. I'd create something like this:

public interface IAssemblyHelper
{
    string GetLocationOfExecutingAssembly();
}

public class AssemblyHelper : IAssemblyHelper
{
    public string GetLocationOfExecutingAssembly()
    {
        return Assembly.GetExecutingAssembly().Location;
    }
}

At runtime, I'd inject AssemblyHelper into the constructor of the class that required it, as IAssemblyHelper. In unit tests, I'd mock IAssemblyHelper, set it up to return an expected path, and pass the mock into the class's constructor.

Testing that the code works with an actual executing assembly's location path in your application should be part of an acceptance test.

Atronna answered 17/7, 2013 at 12:1 Comment(2)
The point using a relative path is so when others who check out your code to a different path than you expect, it will still work. "set it up to return an expected path"/hardcoded path -1Hereupon
@Hereupon You've misunderstood. This has nothing to do with relative paths or checking out code. I'm advocating setting up a mock of IAssemblyHelper to return a known string for the path that can be asserted on in unit tests. In runtime code, the call would go through to the concrete class AssemblyHelper and return the actual executing assembly's location.Atronna
I
5

My colleague suggested a following solution that works for all our use cases:

public static string AssemblyDirectory
{
    get
    {
        string codeBase = Assembly.GetExecutingAssembly().CodeBase;
        var uri = new UriBuilder(codeBase);
        string path = Uri.UnescapeDataString(uri.Path);
        return Path.GetDirectoryName(path);
    }
}
Idolist answered 11/1, 2015 at 9:37 Comment(0)
O
3

Finally, I accomplished this through this way:

I used NUnit Framework and disabled Shadow copying in NUnit. Created a copy of my configuration file in that directory where the unit testing library is invoked.

So, whenever my unit test is invoked (say from path 'A'), my application doesn't complain that there is no configuration file in that location since i put my configuration file in path 'A'.

(ps: The reason why I get the assembly location is to be able to find my configuration file in that location)

[The whole idea is this: with shadow copying, the assembly path is dynamic. disable it and the assembly path is static]

Oloroso answered 6/8, 2013 at 9:21 Comment(4)
How did you turn off the ShadowCopy? I've tried all sorts of code and nothing seems to turn it off. Can you give us a sample?Spirometer
Actually, I disabled shadow copying in NUnit. Go to Tools->Settings and uncheck the Enable Shadow Copy check box. That should do the trick.Oloroso
Ah. I thought that you had removed it from the app. I've been trying to remove it from my desktop app, and nothing seems to work.Spirometer
@Erick: Yup, thats true. I tried to disable it but could not.Oloroso

© 2022 - 2024 — McMap. All rights reserved.