Как проверить, не выдает ли функция исключение?

У меня есть эта функция и тест:

public void SaveForWeb ()
{
    UpdateGameState();
    try
    {
        PlayerPrefs.SetFloat(Helper.EXP_KEY, experience);
        PlayerPrefs.SetFloat(Helper.SCORE_KEY, score);
        // other properties that need to be saved in PlayerPrefs

        PlayerPrefs.Save();
    }
    catch (Exception ex)
    {
        Debug.Log(ex.Message);
    }
}

[Test]
[Category(Helper.TEST_CATEGORY_SAVE_FOR_WEB)]
public void SaveForWebTest ()
{
    // arrange
    var slgdController = FakeSaveLoadGameDataController();
    TestDelegate myDelegate = () => {};

    // act
    slgdController.SaveForWeb();

    // assert
    Assert.DoesNotThrow(myDelegate);
}

Но я чувствую, что между утверждением и вызовом функции SaveForWeb() нет никакой связи.

Примечание. SaveForWeb() использует PlayerPrefs из Unity3D API, что может вызвать исключение PlayerPrefsException, если локальный файл превышает 1 МБ.

Это правильный способ утверждать, что функция не выдает исключение?


person Vlad    schedule 03.03.2016    source источник
comment
Вам не нужно утверждать, что функция не генерирует исключение в модульном тесте. По умолчанию, если в модульном тесте возникает исключение, модульный тест завершается ошибкой из-за неожиданного исключения.   -  person Matthew Watson    schedule 03.03.2016
comment
Да, это дубликат, но ладно, кто-нибудь из сообщества Unity3D может найти его полезным.   -  person Vlad    schedule 03.03.2016
comment
Нет ничего плохого в дубликатах, если они полезны (и предположительно невинны): p   -  person Drew    schedule 04.03.2016


Ответы (5)


Вам не нужно утверждать, если метод не вызывает исключение. Я знаю, что вы используете NUnit, но есть проблема с xUnit, которая объясняет, почему вам не нужно утверждать это. .

Однако, если вы хотите быть явным, вы можете сделать:

[Test]
[Category(Helper.TEST_CATEGORY_SAVE_FOR_WEB)]
public void SaveForWebTest ()
{
    // arrange
    var slgdController = FakeSaveLoadGameDataController();

    Assert.DoesNotThrow(() => slgdController.SaveForWeb());
}
person Marcio Rinaldi    schedule 03.03.2016
comment
Некоторые другие ответы работают, но этот подход дает лучшее сообщение об ошибке в случае сбоя. - person Charlie; 04.03.2016

Если он не генерирует исключение, ваш код должен просто работать и достигать конца тестового метода. Таким образом, вы можете добавить Assert.IsTrue(true) в конце, который вызывается только если метод выполняется без ошибок. В противном случае (при возникновении исключения) тест немедленно остановится и вернет false.

РЕДАКТИРОВАТЬ: Вам даже не нужен вызов Assert.IsTrue, тест также завершится успешно, если он дойдет до конца.

person HimBromBeere    schedule 03.03.2016
comment
Итак, вы хотите сказать, что если SaveForWeb() выдает исключение, выполнение теста остановится на той строке, где он прервался? - person Vlad; 03.03.2016
comment
Да, если возникнет исключение, тест немедленно остановится и вернет false. - person HimBromBeere; 03.03.2016

В своих тестах я просто не делаю утверждений. Если возникнет исключение, тест завершится неудачно, потому что у вас нет атрибута ExpectedException или около того.

Assert.IsTrue(true) бессмысленно имхо

person cdie    schedule 03.03.2016

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

[Test]
[Category(Helper.TEST_CATEGORY_SAVE_FOR_WEB)]
public void SaveForWebTest ()
{
    // arrange
    var slgdController = FakeSaveLoadGameDataController();
    TestDelegate myDelegate = () => {};

    // act
    try
    {
        slgdController.SaveForWeb();
        Assert.IsTrue(true) // Not Actually necessary as should still pass
    }
    catch (Exception ex)
    {
        Assert.Fail("Expected no exception, but got: " + ex.Message);
    }
}
person KevDev    schedule 03.03.2016

Вы должны дать своим модульным тестам более осмысленные имена. Таким образом, вы действительно можете понять из теста, что происходит не так:

    [TestMethod]
    public void SaveForWeb_WhenGameControllerIsOk_DoesNotThrowException()
    {
        // Arrange
        var controller = FakeSaveLoadGameDataController();

        // Act
        controller.SaveForWeb();

        // Assert - Will fail by exceptionThrown
    }

    [TestMethod, ExpectedException(typeof(ReallyBadException))]
    public void SaveForWeb_WhenGameControllerThrowsException_ThrowsException()
    {
        // Arrange
        var controller = new FakeSaveLoadGameDataControllerWithException();

        // Act
        controller.SaveForWeb();
    }
person Pedro G. Dias    schedule 03.03.2016