Как вы тестируете приватные методы? - PullRequest
466 голосов
/ 30 октября 2008

Я создаю библиотеку классов, которая будет иметь несколько открытых и закрытых методов. Я хочу иметь возможность тестировать приватные методы модульно (в основном при разработке, но также может быть полезно для будущего рефакторинга).

Как правильно это сделать?

Ответы [ 31 ]

2 голосов
/ 11 апреля 2012

Вот хорошая статья о модульном тестировании частных методов. Но я не уверен, что лучше сделать приложение специально разработанным для тестирования (это все равно, что создавать тесты только для тестирования) или использовать рефлексию для тестирования. Уверен, большинство из нас выберет второй путь.

2 голосов
/ 24 августа 2009

MbUnit получил хорошую обертку для этого под названием Reflector.

Reflector dogReflector = new Reflector(new Dog());
dogReflector.Invoke("DreamAbout", DogDream.Food);

Вы также можете устанавливать и получать значения из свойств

dogReflector.GetProperty("Age");

Что касается "частного теста", я согласен, что ... в идеальном мире. нет смысла делать частные юнит-тесты. Но в реальности вы можете захотеть написать приватные тесты вместо рефакторинга кода.

2 голосов
/ 21 апреля 2017

Я использую PrivateObject класс. Но, как упоминалось ранее, лучше избегать тестирования частных методов.

Class target = new Class();
PrivateObject obj = new PrivateObject(target);
var retVal = obj.Invoke("PrivateMethod");
Assert.AreEqual(retVal);
1 голос
/ 26 ноября 2016

По моему мнению, вам следует только протестировать открытый API вашего classe.

Обнародование метода для его модульного тестирования нарушает инкапсуляцию, раскрывая детали реализации.

Хороший публичный API решает непосредственную задачу клиентского кода и полностью решает эту задачу.

1 голос
/ 28 сентября 2015

Вы также можете объявить его как открытый или внутренний (с InternalsVisibleToAttribute) при сборке в режиме отладки:

    /// <summary>
    /// This Method is private.
    /// </summary>
#if DEBUG
    public
#else
    private
#endif
    static string MyPrivateMethod()
    {
        return "false";
    }

Он раздувает код, но в выпускной сборке он будет private.

1 голос
/ 18 июня 2015

1) Если у вас есть унаследованный код, то единственный способ проверить закрытые методы - это рефлексия.

2) Если это новый код, у вас есть следующие опции:

  • Использовать отражение (для сложных)
  • Написать модульный тест в том же классе (делает рабочий код уродливым с тестовым кодом также в нем)
  • Рефакторинг и обнародование метода в некотором классе утилит
  • Используйте аннотацию @VisibleForTesting и удалите приватную

Я предпочитаю метод аннотации, самый простой и наименее сложный. Единственная проблема заключается в том, что мы увеличили видимость, что, я думаю, не является большой проблемой. Мы всегда должны кодировать интерфейс, поэтому если у нас есть интерфейс MyService и реализация MyServiceImpl, то у нас могут быть соответствующие тестовые классы, такие как MyServiceTest (методы интерфейса тестирования) и MyServiceImplTest (тестировать частные методы). В любом случае все клиенты должны использовать интерфейс таким образом, что хотя видимость приватного метода была увеличена, это не должно иметь большого значения.

1 голос
/ 22 сентября 2014

Способ сделать это состоит в том, чтобы иметь свой метод protected и написать тестовое устройство, которое наследует ваш класс для тестирования. Таким образом, вы не поворачиваете свой метод public, но включаете тестирование.

1 голос
/ 17 мая 2012

Вот пример, сначала подпись метода:

private string[] SplitInternal()
{
    return Regex.Matches(Format, @"([^/\[\]]|\[[^]]*\])+")
                        .Cast<Match>()
                        .Select(m => m.Value)
                        .Where(s => !string.IsNullOrEmpty(s))
                        .ToArray();
}

Вот тест:

/// <summary>
///A test for SplitInternal
///</summary>
[TestMethod()]
[DeploymentItem("Git XmlLib vs2008.dll")]
public void SplitInternalTest()
{
    string path = "pair[path/to/@Key={0}]/Items/Item[Name={1}]/Date";
    object[] values = new object[] { 2, "Martin" };
    XPathString xp = new XPathString(path, values);

    PrivateObject param0 = new PrivateObject(xp);
    XPathString_Accessor target = new XPathString_Accessor(param0);
    string[] expected = new string[] {
        "pair[path/to/@Key={0}]",
        "Items",
        "Item[Name={1}]",
        "Date"
    };
    string[] actual;
    actual = target.SplitInternal();
    CollectionAssert.AreEqual(expected, actual);
}
0 голосов
/ 29 мая 2010

Вы можете сгенерировать тестовый метод для частного метода из Visual studio 2008. Когда вы создаете модульный тест для частного метода, папка «Ссылки на тест» добавляется в ваш тестовый проект, а средство доступа добавляется в эту папку. Метод доступа также упоминается в логике метода модульного тестирования. Этот метод доступа позволяет вашему модульному тесту вызывать закрытые методы в тестируемом коде. Для получения более подробной информации посмотрите на

http://msdn.microsoft.com/en-us/library/bb385974.aspx

0 голосов
/ 29 января 2018

Для языка JAVA

Здесь вы можете переопределить конкретный метод класса тестирования с помощью фиктивного поведения.

Для приведенного ниже кода:

public class ClassToTest 
{
    public void methodToTest()
    {
        Integer integerInstance = new Integer(0);
        boolean returnValue= methodToMock(integerInstance);
        if(returnValue)
        {
            System.out.println("methodToMock returned true");
        }
        else
        {
            System.out.println("methodToMock returned true");
        }
        System.out.println();
    }
    private boolean methodToMock(int value)
    {
        return true;
    }
}

Тестовый класс будет:

public class ClassToTestTest{

    @Test
    public void testMethodToTest(){

        new Mockup<ClassToTest>(){
            @Mock
            private boolean methodToMock(int value){
                return true;
            }
        };

        ....    

    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...