Поведение юнит-теста после исключения выдается? - PullRequest
3 голосов
/ 18 июля 2010

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

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

 public T CreateTypedObjectInstance<T>()
 {
     T o = default(T);
     try
     {
         o = Activator.CreateInstance<T>();
     }
     catch (Exception ex)
     {
         LogError(ex);
         throw ex;
     }
     return o;
 }

 private void LogError(Exception ex)
 {
     if (logger != null)
     {
        logger.LogError(ex);
     }
 }

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

Я подошел к этому с помощью макета для логгера и поймал первое выброшенное исключение, а затем подтвердил, что был вызван метод LogError. Тем не менее, это не кажется правильным, когда нужно поймать исключение? Я помню, читал что-то, что это плохо, чтобы попробовать ловит в тестах? Есть ли другой способ выполнить этот тест, или я должен рефакторинг логики? Любые идеи будут великолепны!

      [Test]
    public void CreateTypedObjectInstance_GivenTypeWithoutPrivateContructor_LogErrorToLogger()
    {
        //Setup Method used
        MockRepository mockery = new MockRepository();
        ILogger mockedLogger = mockery.StrictMock<ILogger>();
        genericObjectFactoryInstance.Logger = mockedLogger;
        Expect.Call( delegate { mockedLogger.LogError(null); } ).IgnoreArguments();
        mockery.ReplayAll();
        // this will throw an error as String does not have a parameterless constructor
        try
        {
            genericObjectFactoryInstance.CreateTypedObjectInstance<String>();
        }
        catch { /*ignore this error to test behaviour after*/ }
        mockery.VerifyAll();
    }

EDIT

Используя ответ Марка Рушакова, тест становится и работает как шарм.

        [Test]
    public void CreateTypedObjectInstance_GivenTypeWithoutPrivateContructor_LogErrorToLogger()
    {
        //Setup Method used
        MockRepository mockery = new MockRepository();
        ILogger mockedLogger = mockery.StrictMock<ILogger>();
        genericObjectFactoryInstance.Logger = mockedLogger;
        Expect.Call( delegate { mockedLogger.LogError(null); } ).IgnoreArguments();
        mockery.ReplayAll();
        Assert.Throws<MissingMethodException>(() => genericObjectFactoryInstance.CreateTypedObjectInstance<String>());
        mockery.VerifyAll();
    }

Ответы [ 3 ]

7 голосов
/ 18 июля 2010

Вы не сказали, какую версию NUnit вы используете, но предпочтительным подходом будет метод Assert.Throws.

Assert.Throws<YourCustomException>(() => GenericObjectFactoryInstance.CreateTypedObjectInstance<String>());

@ Ответ Бруно уместен, если ваша тестовая среда не предлагает средства для проверки на наличие исключений.

2 голосов
/ 18 июля 2010

На самом деле модульный тест может проверить, было ли выброшено исключение при выполнении условия исключения. Например:

Метод:

public int getCalc(int a, int b) throws SampleException {
   if (a > b) {
      throw new SampleException();
   }
   // (..)
}

Тест:

public void testGetCalcException() {

   try {
     getCalc(2,1); // 2 > 1  exception is expected
     fail("SampleException was expected but was not thrown");       

   } catch(SampleException e) {
      // great - test passed!
   } 

}
0 голосов
/ 18 июля 2010

Если вы используете NUnit в качестве среды тестирования UT, вы можете использовать атрибут ExpectedException, чтобы проверить, действительно ли метод вызывает ожидаемое исключение или нет.этот подход не требует, чтобы вы пытались поймать блоки в тестовом коде.

Для получения более подробной информации вы можете посмотреть в следующем примере Пример ExpectedException

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