如何断言当在测试方法中抛出并捕获异常时,方法 returns 是布尔值?

How to assert that when an exception is thrown and caught within the tested method, the method returns a boolean?

我有以下接口来执行模拟:

public interface IIOManager
{
    void WriteAllText(string fullPath, string aFileContents);
    string ReadAllText(string fullPath);
}

我正在测试这个静态 class

using UnityEngine;

public static class FileManager
{    public static bool LoadFromFile(string fullPath, out string result, IIOManager iOFile)
    {
        bool val;
        try
        {
            result = iOFile.ReadAllText(fullPath);
            val = true;
        }
        catch (System.Exception e)
        {
            Debug.LogError($"Failed to read from {fullPath} with exception {e}");
            result = string.Empty;
            val = false;
        }
        return val;
    }
}

在最小起订量中,为了测试静态 class,我要做的是:

using Moq;
using NUnit.Framework;

namespace Tests
{
    public class FileManagerTests
    {
        private Mock<IIOManager> iOManager;
        private string result = string.Empty;
        private readonly string fullPath = "fullPath";
        private readonly string aFileContents = "aFileContents";

        [SetUp]
        public void SetUp()
        {
            iOManager = Mock<IIOManager>();
            iOManager.Setup( (io) => io.ReadAllText(It.IsAny<string>()))
                .Returns(result);
        }

        [Test]
        public void LoadFromFile_WhenSuccessful_ReturnsTrue()
        {
            iOManager.ReadAllText(fullPath).Returns(aFileContents);
            Assert.IsTrue(FileManager.LoadFromFile(fullPath, out var result, iOManager.Object));
        }

        [Test]
        public void LoadFromFile_ExceptionIsThrown_ReturnsFalse()
        {
            iOManager.Setup( (io) => io.ReadAllText(It.IsAny<string>()))
                .Returns("").Throws<System.Exception>();
            Assert.IsFalse(FileManager.LoadFromFile(fullPath, out var result, iOManager.Object));
        }
    }
}

但是,当我尝试执行 Moq 等效时,我无法断言其 return 值,因为在测试时未捕获到异常,给定调试控制台的状态。

using NSubstitute;
using NUnit.Framework;
using NSubstitute.ExceptionExtensions;

namespace Tests
{
    public class FileManagerTests
    {
        private IIOManager iOManager;
        private string result = string.Empty;
        private readonly string fullPath = "fullPath";
        private readonly string aFileContents = "aFileContents";

        [SetUp]
        public void SetUp()
        {
            iOManager = Substitute.For<IIOManager>();
            iOManager.ReadAllText(Arg.Any<string>()).Returns(result);
        }

        [Test]
        public void LoadFromFile_WhenSuccessful_ReturnsTrue()
        {
            iOManager.ReadAllText(fullPath).Returns(aFileContents);
            Assert.IsTrue(FileManager.LoadFromFile(fullPath, out var result, iOManager));
        }

        [Test]
        public void LoadFromFile_ExceptionIsThrown_ReturnsFalse()
        {
            iOManager.ReadAllText(fullPath).Throws<System.Exception>();
            Assert.IsFalse(FileManager.LoadFromFile(fullPath, out var result, iOManager));
        }
    }
}

我尝试在 Whosebug 上搜索类似的问题来寻找解决方案。但是,那些主要是无效方法,而不是断言 returned 值。

我正在使用 Unity Test Framework 1.1.3.1,它带有 NUnit 3.5 库的 Unity 集成。

您正在测试的方法 (LoadFromFile)return是一个布尔值,如果没有抛出异常则为真。

您的代码已经测试了这两个条件。

如果您还想测试 out 变量的值,您可以在单独的 Assert 语句中执行此操作,紧跟在现有语句之后。

您使用的 mock 不能同时 return 值和抛出,因此为了清楚起见,您应该在设置中删除 Returns 语句。