首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >是否有可能在不修改每个测试和/或夹具的代码的情况下模拟NUnit测试的失败?

是否有可能在不修改每个测试和/或夹具的代码的情况下模拟NUnit测试的失败?
EN

Stack Overflow用户
提问于 2019-03-20 12:03:33
回答 1查看 66关注 0票数 1

我希望能够模拟任意测试的失败,以便检查我的TearDown逻辑是否正常工作。如果您愿意,可以在单元测试上进行单元测试。

但实际上,我在一些fixtures中使用了TearDown,它可以在失败时生成附件。我必须能够展示这个特性,但在您最需要它的时候很难产生故障。

因此,我想创建一个test参数,指定我希望失败的测试的名称。现在,我可以很容易地编写实现IWrapTestMethodIApplyToContext的属性,但接下来我需要将其应用于每个测试方法。

有没有一种方法可以在不涉及每个测试和/或装置的情况下实现它?通过在每次测试之前运行的某种程序集级属性或程序集级设置方法?

至关重要的是,此逻辑不会阻止TearDown方法的运行,因此ITestActionBeforeTest抛出异常并不符合要求。

这可以做到吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-03-21 06:58:27

我找到了解决方案:

代码语言:javascript
运行
复制
using NUnit.Framework;
using NUnit.Framework.Interfaces;
using NUnit.Framework.Internal;
using System;
using System.Reflection;

[assembly: Common.EnableFailureSimulation]

namespace Common
{
    public class SimulateFailureMethodInfoWrapper : IMethodInfo
    {
        private readonly IMethodInfo m_mi;

        public SimulateFailureMethodInfoWrapper(IMethodInfo mi)
        {
            m_mi = mi;
        }

        public ITypeInfo TypeInfo => m_mi.TypeInfo;

        public MethodInfo MethodInfo => m_mi.MethodInfo;

        public string Name => m_mi.Name;

        public bool IsAbstract => m_mi.IsAbstract;

        public bool IsPublic => m_mi.IsPublic;

        public bool ContainsGenericParameters => m_mi.ContainsGenericParameters;

        public bool IsGenericMethod => m_mi.IsGenericMethod;

        public bool IsGenericMethodDefinition => m_mi.IsGenericMethodDefinition;

        public ITypeInfo ReturnType => m_mi.ReturnType;

        public T[] GetCustomAttributes<T>(bool inherit) where T : class => m_mi.GetCustomAttributes<T>(inherit);

        public Type[] GetGenericArguments() => m_mi.GetGenericArguments();

        public IParameterInfo[] GetParameters() => m_mi.GetParameters();

        public object Invoke(object fixture, params object[] args)
        {
            var res = m_mi.Invoke(fixture, args);
            Assert.Fail("Failure simulation");
            return res;
        }

        public bool IsDefined<T>(bool inherit) where T : class => m_mi.IsDefined<T>(inherit);

        public IMethodInfo MakeGenericMethod(params Type[] typeArguments) => m_mi.MakeGenericMethod(typeArguments);
    }

    [AttributeUsage(AttributeTargets.Assembly)]
    public class EnableFailureSimulationAttribute : Attribute, ITestAction
    {
        private static string s_failTestMethod = GetParameterByName("!");

        public ActionTargets Targets => ActionTargets.Test;

        public void AfterTest(ITest test)
        {
        }

        public void BeforeTest(ITest test)
        {
            if (test.MethodName == s_failTestMethod && test is Test testImpl)
            {
                testImpl.Method = new SimulateFailureMethodInfoWrapper(testImpl.Method);
                s_failTestMethod = "!";
            }
        }
    }
}

另一种方法是使用Moq并模拟IMethodInfo接口,而不是使用真正的SimulateFailureMethodInfoWrapper类。

无论如何,这似乎是完美的工作。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55253424

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档