Методы юнит-тестирования, содержащие операторы using - PullRequest
5 голосов
/ 11 декабря 2008

Мне интересно, могут ли операторы Unittesting и using действительно идти рука об руку, поскольку нет способа высмеять одноразовый объект, созданный в выражении using. Как я смогу эффективно протестировать метод, содержащий следующую инструкцию using?

public void MyMethod()
{
   using(MyDisposableClass disp = new MyDisposableClass())
   {
       ...
   }
}

Запрещено ли использование операторов просто при юнит-тестировании?

Любые комментарии приветствуются.

Ответы [ 4 ]

4 голосов
/ 11 декабря 2008

Нет, использование утверждений, безусловно, не запрещено. Но что на самом деле делает MyDisposableClass? Меня поражает, что дело не в том, что оператор using является проблемой, а в том, как метод создает новый объект, который вы хотите смоделировать - это проблема.

Вам действительно нужно издеваться над MyDisposableClass? Можно ли передать его в MyMethod вместо создания внутри него? Как всегда, хитрость заключается в том, чтобы понять, как подключиться к процессу и внедрить свои собственные объекты, когда вам нужно ...

3 голосов
/ 11 декабря 2008

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

interface IResource : IDisposable
{
        void DoSomething();
}

class DisposableResource : IResource
{
    public void Dispose()       {  Console.WriteLine("That's it. I'm outta here!");  }
    public void  DoSomething()  {  Console.WriteLine("Hard work this");  }
}

Чтобы ввести объект, вам нужен шов .. т.е. GetResource ()

class MyClass
{
    protected virtual IResource GetResource()
    {
        return new DisposableResource();
    }
    public void MyMethod1()
    {
        using (IResource r = GetResource())
        {
            r.DoSomething();
        }
    }
}

В вашем тестовом коде просто создайте подкласс и переопределите GetResource (), чтобы вернуть макет.

class MySubClassForTest : MyClass
{
    protected override IResource GetResource()
    {
        return new MockResource();
    }
}
class MockResource : IResource    // or use a mock framework to create one
{
    public void  DoSomething()        { Console.WriteLine("Me work?"); }
    public void  Dispose()            { Console.WriteLine("Disposed Mock!"); }
}

Вот и все.

 MyClass obj = new MyClass();           // production code
 obj.MyMethod1();

 obj = new MySubClassForTest();         // test code
 obj.MyMethod1();
1 голос
/ 11 декабря 2008

TypeMock позволит вам поиздеваться над этим. Он работает, изменяя IL на лету и, таким образом, не имеет проблем с дразнить вещи, которые вы иначе не можете издеваться.

Но даже с TypeMock вы все равно должны взглянуть на то, что Джон Скит и Поп Каталин говорят выше. Ваш код будет легче поддерживать, если вы попытаетесь уменьшить количество зависимостей.

1 голос
/ 11 декабря 2008

Использование фабричного шаблона и / или шаблона внедрения зависимостей значительно упростит способ юнит-методов тестирования, которые создают свои собственные ресурсы.

Вот хорошее прочтение на эту тему:

...