2016-03-31 3 views
2

Пытается издеваться над методом, который вызывается в рамках другого метода.Откажитесь от метода тестирования

public virtual bool hello(string name, int age) 
{ 

    string lastName = GetLastName(); 
} 

public virtual string GetLastName() 
    { 
     return "xxx"; 
    } 

Mock<program> name= new Mock<program>(); 
name.Setup(x => x.GetLastName()).Returns("qqq"); 

Я хочу, чтобы метод GetLastName всегда возвращал «qqq».

+0

Какая у вас проблема с тем, что вы пробовали? что выглядит правильно – Kritner

+0

Значение моей фамилии по-прежнему равно = xxx, когда я поставил точки останова. Также не удалось выполнить единичный тест – codeislife

ответ

1

Это должно работать, если те полные реализации методов

public class MyProgram 
{ 

    public bool hello(string name, int age) 
    { 
     string lastName = GetLastName(); 

     return string.Format("hello {0}", lastName); 
    } 

    public virtual string GetLastName() 
    { 
     return "xxx"; 
    } 
} 

public class MyProgramTests 
{ 

    [TestMethod] 
    public void MyTest() 
    { 

     string stringToReturn = "qqq"; 
     Mock<MyProgram> name = new Mock<MyProgram>(); 
     name.CallBase = true; 
     name.Setup(x => x.GetLastName()).Returns(stringToReturn); 

     var results = name.Object.hello(It.IsAny<string>(), It.IsAny<int>()); 

     string expected = string.Format("hello {0}", results); 

     Assert.AreEqual(expected, results); 
    } 
} 

Я до сих пор не совсем следующий комментарий:

Что означает параметр действительно имею в виду, Мок Что нужно ?? быть? извините, я не совсем понимаю синтаксис. Чтобы уточнить, издевательство означает, что когда я добавляю точки останова в свой код I, точки останова должны пропускать методы, которые я издеваюсь. Я прав?

Mock<T> позволяет издеваться тип T - T является общим показателем, также означает, что угодно, что это класс. В традиционном, вы бы издевались над interface, а не с фактическим class, но в приведенном выше примере мы издеваемся над классом. Для проведенного испытания единицы измерения образца цель модульного испытания заключается в проверке реализации hello(string, int). Мы знаем, что hello(string, int) полагается на другой метод в этом классе, который называется GetLastName(). GetLastName() s реализация, хотя и важная, не важна для объема модульных испытаний hello(string, int). По этой причине мы издеваемся над вызовом и его возвратом - чтобы проверить функциональность hello(string, int), не беспокоясь о его реализации зависимостей.

Я окружил выше с реальными именами классов, мы надеемся сделать его более очевидным, что мы насмешливый класс MyProgram и обеспечивая новую реализацию (макет) из GetLastName()

Спасибо за ответ. Что делать, если я хочу протестировать метод, который вызывает другой метод, который вызывает другой метод? Напр. что, если метод hello называется другим методом?

Тот же принцип применяется, когда вы создаете модульные тесты (при условии, что они являются блок тестов, а не интеграции тесты или другие, вы всегда хотите, чтобы сосредоточиться на тестировании один общественности метод. What's the difference between unit and integration tests?

public class Foo 
{ 

    public string Bar() 
    { 
     return string.Format("{0}Bar", Baz(5));; 
    } 

    public virtual string Baz(int someNumber) 
    { 
     return string.Format("{0}Baz", DoStuff(someNumber).ToString()); 
    } 

    public virtual int DoStuff(int someNumber) 
    { 
     return someNumber+1; 
    } 

} 

Если мы модульное тестирование Bar() мы не заботимся о выполнении Baz(int) или даже хуже DoStuff(int). Примечание Мы не заботимся об осуществлении, мы do заботимся о том, чтобы они возвращали значения. От Bar() s перспектива, единственное, что важно, это Baz(int) возвращает строку. Какая строка? Не имеет значения для модульного теста Bar().

Образец теста для Bar():

[TestMethod] 
public void Bar_ReturnsBazValueWithBarAppended 
{ 
    // Arrange 
    string testBazReturn = "test"; 
    Mock<Foo> mock = new Mock<Foo>(); 
    mock.CallBase = true; 
    mock 
     .Setup(s => s.Baz(It.IsAny<int>()) 
     .Returns(testBazReturn); 

    // Act 
    var results = mock.Object.Bar(); 

    // Assert 
    Assert.AreEqual(string.Format("{0}{1}", testBazReturn, "Bar"), results); 
    mock.Verify(v => v.Baz(It.IsAny<int>())); // Verifies that Baz was called 
} 

Обратите внимание, в приведенном выше, наши фактические реализации Baz(int) и DoStuff(int) не имеет значения, как мы пренебрегаем фактическую реализацию Baz(int) и DoStuff(int) даже не пришел в игру.

Теперь, если мы должны были проверить Baz(int) мы просто следовать тем же менталитет:

[TestMethod] 
public void Baz_ReturnsDoStuffValueWithBazAppended 
{ 
    // Arrange 
    int testDoStuffReturn = 1; 
    Mock<Foo> mock = new Mock<Foo>(); 
    mock.CallBase = true; 
    mock 
     .Setup(s => s.DoStuff(It.IsAny<int>()) 
     .Returns(testDoStuffReturn); 

    // Act 
    var results = mock.Object.Baz(5); 

    // Assert 
    Assert.AreEqual(string.Format("{0}{1}", results, "Baz"), results); // Validates the result 
    mock.Verify(v => v.DoStuff(It.IsAny<int>())); // Verifies that DoStuff was called 
} 

В приведенном выше, теперь, когда мы модульное тестирование Baz(int), мы не заботимся о Bar(), и только что мы заботимся о в DoStuff(int) является то, что она возвращает значение (но не как он достигнет этой величины.)

И наконец DoStuff(int):

[TestMethod] 
public void DoStuff_ReturnsParameterPlusOne() 
{ 
    // Arrange 
    Foo foo = new Foo(); 
    int passed = 1; 
    int expected = passed + 1; 

    // Act 
    var results = foo.DoStuff(passed); 

    // Assert 
    Assert.AreEqual(expected, results); 
} 
+0

, следует ли использовать базовый или расширенный класс или это не имеет значения для программы? (параметр в Mock) – codeislife

+0

Я не понимаю ваш вопрос, можете ли вы подробно рассказать о проблемах с образцами того, что вы имеете в виду? – Kritner

+0

Что этот параметр действительно означает Mock Что должно? быть? извините, я не совсем понимаю синтаксис. Чтобы уточнить, издевательство означает, что когда я добавляю точки останова в свой код I, точки останова должны пропускать методы, которые я издеваюсь. Я прав? – codeislife

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