2017-02-02 4 views
0

Как проверять частные статические общие методы? Внутренние элементы видны моему тестовому проекту. Как можно проверить эти методы?Тестирование частных статических общих методов в C#

internal class Foo { 

    // Non-static. This works! 
    private T TestThisMethod1<T>(T value) { 
     Console.WriteLine("Called TestThisMethod1"); 
     return value; 
    } 

    // Static. Can't get this to work! 
    private static T TestThisMethod2<T>(T value) { 
     Console.WriteLine("Called TestThisMethod2"); 
     return value; 
    } 

    // Static. Can't get this to work! 
    private static void TestThisMethod3<T>(T value) { 
     Console.WriteLine("Called TestThisMethod3"); 
    } 

    // Static. Can't get this to work! 
    private static void TestThisMethod4<T, T2>(T value, T2 value2) { 
     Console.WriteLine("Called TestThisMethod4"); 
    } 
} 

Первый пример работ. Это не статично. Это пример от https://msdn.microsoft.com/en-us/library/bb546207.aspx.

[TestMethod] 
public void PrivateStaticGenericMethodTest() { 

    int value = 40; 
    var foo = new Foo(); 

    // This works. It's not static though. 
    PrivateObject privateObject = new PrivateObject(foo); 
    int result1 = (int)privateObject.Invoke("TestThisMethod1", new Type[] { typeof(int) }, new Object[] { value }, new Type[] { typeof(int) }); 

    // Fails 
    int result2 = (int)privateObject.Invoke("TestThisMethod2", BindingFlags.Static | BindingFlags.NonPublic, new Type[] { typeof(int) }, new Object[] { value }, new Type[] { typeof(int) }); 

    // Fails 
    PrivateType privateType = new PrivateType(typeof(Foo)); 
    int result2_1 = (int)privateType.InvokeStatic("TestThisMethod2", new Type[] { typeof(int) }, new Object[] { value }, new Type[] { typeof(int) }); 

    // Fails 
    int result2_2 = (int)privateType.InvokeStatic("TestThisMethod2", BindingFlags.Static | BindingFlags.NonPublic, new Type[] { typeof(int) }, new Object[] { value }, new Type[] { typeof(int) }); 

    // Stopping here. I can't even get TestThisMethod2 to work... 
} 

Моя цель в письменном виде не совсем на вопрос или обсуждать достоинство тестирования частных методов: Это было подвергнуто обсуждавшейся снова и снова. Более того, моя цель в написании вопроса состоит в том, чтобы сказать: «Это должно быть возможно сделать с помощью PrivateObject или PrivateType. Итак, как это можно сделать?»

+2

Есть ли у вас какие-либо потребители вашего частного статического метода? Если нет, то зачем тестировать его поведение? –

+7

Обычно частные методы проверяются с помощью общедоступных методов, которые вызывают их –

+0

Правда, я обычно придерживаюсь нормы «Только проверить публичные методы». В эти дни я ненавижу делать что-либо общедоступным, если я могу избежать этого. Этот метод очень похоронен в коде. Я должен уметь тестировать этот метод отдельно от PrivateObject или PrivateType. – clarionprogrammer

ответ

5

Вы не должны проверять частные методы. Потому что это детали реализации, которые могут измениться. Вы должны проверить свой публичный интерфейс.

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

+1

Я не всегда соглашаюсь с жестким и быстрым правилом «Вы не должны проверять частные методы». Предположим, у вас было сложное консольное приложение с открытой точкой входа, не могли бы вы что-нибудь проверить? Я бы не хотел менять доступность метода только потому, что хочу его протестировать. – clarionprogrammer

+0

Если ваше консольное приложение недостаточно модульно и имеет только основную точку входа, это либо быстрый взлом для чего-то, что не стоит писать модульные тесты для ... или это нестандартный дизайн программного обеспечения. Консольное приложение - это пользовательский интерфейс ... ваш бизнес и слои данных не должны быть частными. – nvoigt

+0

Консольное приложение было всего лишь примером ... Мое намерение - не обсуждать ценность тестирования частных методов или нет. Microsoft увидела ценность в создании классов PrivateObject и PrivateType для проверки частных методов. Я пытаюсь понять, как правильно их использовать. – clarionprogrammer

2

Наконец-то нашел способ сделать это с поиском Google для тестирования с помощью общих типов. Используя объект, его собственный запрос, метод затем запускается через вызов метода generic метода и, наконец, вызывает его.

[TestMethod] 
public void TestMethod2() 
{ 
    int value = 40; 
    var foo = new Foo(); 

    MethodInfo fooMethod = foo.GetType().GetMethod("TestThisMethod2", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Instance); 
    if (fooMethod == null) 
    { 
     Assert.Fail("Could not find method"); 
    } 
    MethodInfo genericFooMethod = fooMethod.MakeGenericMethod(typeof(int)); 
    int result1 = (int)genericFooMethod.Invoke(typeof(int), new object[] { value }); 

    Assert.AreEqual(result1, value); 
} 
+0

Это решение, и оно отвечает на вопрос. Я ожидал, что PrivateObject или PrivateType могут сделать это за кулисами, не выполняя при этом отражение. К сожалению, похоже, что ни один из них не будет работать в этом конкретном сценарии. – clarionprogrammer

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