2015-02-20 4 views
2

Я пытаюсь использовать FakeItEasy. У меня есть конкретный сценарий, для которых либо я не в состоянии понять, как проверить или не представляется возможным с помощью FakeItEasyКак я могу использовать метод базового класса с использованием FakeItEasy

Допустим, у меня есть базовый класс и производный класс, который похож на этот

public class BaseClass { 
    protected bool BaseClassMethod() { return true; } 
    } 

public class DerivedClass : BaseClass { 
    public void DoSomething(){ 
     if(BaseClassMethod()) Console.WriteLine("Bla"); 
     else Console.WriteLine("Worked"); 
    } 
} 

Теперь я хочу быть в состоянии проверить DerivedClass, но иметь возможность подделать BaseClassMethod(). Я попытался сделать что-то вроде

var fakeBaseClass = A.Fake<BaseClass>(); 
A.CallTo(fakedBaseClass).Where(x => x.Method.Name "BaseClassMethod")).WithReturnType<bool>(). Returns(false); 
var derivedClass = new DerivedClass(); // Am hoping that the DerivedClass will use the Faked Baseclass that I have created above. 
derivedClass.DoSomething() 

Это не делает то, что я ожидаю от него. Мне что-то не хватает, или это невозможно с FakeItEasy?

Благодаря Karthik

ответ

1

Есть несколько проблем, с вашим подходом.

Первой проблемой является то, что у вас нет связи между созданным вами fakeBaseClass и derivedClass, поэтому нет возможности влиять на них. Чтобы выполнить то, что, как я думаю, вы пытаетесь сделать, вы действительно хотите сделать подделку и манипулировать ее поведением (на самом деле, в общем, этот тип тестирования является спорным, но давайте сосредоточимся на механике и отложим, хорошая ли это идея на данный момент).

фальсифицируя DerivedClass, FakeItEasy на самом деле будет инстанцирование нового типа класса, который производных от DerivedClass и, следовательно, будет звонить и иметь доступ ко всем (защищенным или общественным) методам DerivedClass и BaseClass. Затем вы можете настроить поведение, которое вы хотите, с BaseClassMethod и провести DoSomething и, надеюсь, получить нужные результаты.

Вторая вещь, которая вызовет проблемы, когда мы попробуем это, - это то, что BaseClassMethod не является виртуальным. FakeItEasy (и рамки изоляции его ilk) не могут подделать любой метод, который не является виртуальным. Вы можете узнать больше о том, что подделано на What can be faked.

Итак, положив вместе эти два изменения, я получаю примерно такой код:

public class BaseClass 
{ 
    protected virtual bool BaseClassMethod() 
    { 
     return true; 
    } 
} 

public class DerivedClass : BaseClass 
{ 
    public string DoSomething() 
    { 
     if (BaseClassMethod()) 
     { 
      return ("Bla"); 
     } 
     else 
     { 
      return ("Worked"); 
     } 
    } 
} 

[Test] 
public void MethodName_StateUnderTest_ExpectedBehavior() 
{ 
    var fakedDerivedClass = A.Fake<DerivedClass>(); 
    A.CallTo(fakedDerivedClass) 
     .Where(x => x.Method.Name == "BaseClassMethod") 
     .WithReturnType<bool>() 
     .Returns(false); 

    Assert.That(fakedDerivedClass.DoSomething(), Is.EqualTo("Worked")); 
} 

Этот тест проходит. Обратите внимание, что я внес изменения в оригинал (кроме корригирующих опечаток):

  1. BaseClassMethod теперь виртуальный
  2. Я создаю поддельные DerivedClass для тестирования и
  3. DoSomething возвращает строку, а чем писать на консоль. Это не было строго необходимо, но мой тест стал легче писать.

Обратите внимание, что если BaseClassMethod не является виртуальным, то нет никаких шансов, он будет возвращать ничего, кроме true, и я не вижу особого смысла в написании тест, чтобы увидеть, что произойдет, когда DoSomething получает false от него ,

Более подробное обсуждение о том, почему подделке класс тестируемой (вместо сотрудников этого класса) может быть плохой идеей, почитайте комментарии на Use FakeItEasy's A.CallTo() on another method in same object и мой ответ на Using FakeItEasy, is it possible to create a dummy object of a type that takes generic type parameters.

Но как вы относитесь к подходу, вам придется смириться с самим собой.

+0

Спасибо за ваш комментарий. Ваш ответ был до такой степени и хорошо написан –

+0

@ KarthikBalasubramanian, рад, что это помогло. –

Смежные вопросы