Получить каталог приложения как в консольном приложении, так и в его модульных тестах

У меня есть проект консольного приложения с тестами NUnit в том же проекте.

Я пытался применить это решение.

Во время выполнения решение работало нормально. Но когда я запускал тесты Resharper test runner или NUnit GUI runner, GetExecutingAssembly().Location вернул такой путь: d:\Temp\f4ctjcmr.ofr\nojeuppd.fmf\R2Nbs\assembly\dl3\9766f38e\b9496fb3_43cccf01\.
Отключение теневого копирования устранило проблему в обоих средствах запуска тестов, но появились новые проблемы (VS не может построить проект до закрытия NUnit Gui). Есть ли лучшее решение, чем отключение теневого копирования?

Обновление: Environment.GetCommandLineArgs()[0] вернул C:\Program Files (x86)\NUnit 2.6.3\bin\ в тестах, запущенных в NUnit Gui с включенным теневым копированием.


person Andrej Adamenko    schedule 09.09.2014    source источник


Ответы (2)


Хорошо, это относится к интересным.

Вы должны высмеивать эту зависимость.

Пример кода:

public interface IApplicationRootService {
    Uri GetApplicationRoot();
}

public class ApplicationRootService : IApplicationRootService {
    public Uri GetApplicationRoot() {
        //etc
    }
}

Теперь обильно примените к своему коду, в котором вы вызываете getexecutingassembly и тому подобное. Внедрите IApplicationRootService как зависимость конструктора.

Ex:

public class DoWork {
    private IApplicationRootService _applicationRootService;
    public DoWork(IApplicationRootService applicationRootService) {
        _applicationRootService = applicationRootService;
    }
    public void DoSomething() {
        var appRoot = _applicationRooService.GetApplicationRoot();
        //do your stuff
    }
}

Теперь, когда вы тестируете, используйте службу имитации и имитируйте возвращаемое значение корневого каталога приложения в соответствующую папку, чтобы nunit мог начать поиск.

Ex-код с использованием nunit и moq:

[Test]
public static void test_do_something() {
    var applicationRootService = new Mock<IApplicationRootService>();
    applicationRootService.Setup(service => service.GetApplicationRoot()).Returns(new Uri("MyRoot", UriKind.Relative);
    var myClass = new DoWork(applicationRootService.Object);
    //continue testing!
}
person C Bauer    schedule 09.09.2014
comment
Спасибо за ответ. Я, наверное, так и сделаю, если у меня не будет лучшего варианта. - person Andrej Adamenko; 09.09.2014

Для меня сработало решение следующее. Пожалуйста, проголосуйте за его автора, если он вам поможет.

Как объясняется в сообщении на форумах MSDN, Как преобразовать путь URI в обычный путь к файлу?, я использовал следующее:

// Get normal filepath of this assembly's permanent directory
var path = new Uri(
        System.IO.Path.GetDirectoryName(
        System.Reflection.Assembly.GetExecutingAssembly().CodeBase)
    ).LocalPath;
person Andrej Adamenko    schedule 09.09.2014