C# 在MSTest中为共享测试使用继承

C# 在MSTest中为共享测试使用继承,c#,unit-testing,dynamics-crm,mstest,C#,Unit Testing,Dynamics Crm,Mstest,我正在尝试为D365插件和CodeActivities(都是类)编写单元测试。每个插件都应该运行一些小测试,例如: [TestMethod] public void NullLocalPluginContext() { XrmFakedContext context = new XrmFakedContext(); Assert.ThrowsException<InvalidPluginExecutionException>( () => co

我正在尝试为D365插件和CodeActivities(都是类)编写单元测试。每个插件都应该运行一些小测试,例如:

[TestMethod]
public void NullLocalPluginContext()
{
    XrmFakedContext context = new XrmFakedContext();

    Assert.ThrowsException<InvalidPluginExecutionException>(
        () => context.ExecutePluginWith<SomePlugin>(null));
}
对于这些小测试,我希望有一个共享测试的父级,但我不知道如何引用“未来”子级的目标。 我更喜欢MSTest,但任何NuGet框架都可以接受

每个插件都有自己的测试类。 每个pluginest类都需要基本的。 这些基本测试应该从父级继承(这样它们就不会占用空间)

插件:狗、猫、老鼠 插件测试:狗测试、猫测试、鼠标测试
BasePluginTest->应该有共享测试,其中exmaple中的
SomePlugin
是Dog/Cat/Mouse。但我不知道如何引用它。每个插件都有一个函数
TestWalk(){..ExecutePluginWith}
。猫应该调用CatTest,狗应该调用DogTest。

免责声明:有些人不喜欢这样,因为它滥用类继承来保存代码。这是一个潜在的工作工具,你可以评估它是否适合你

这似乎可以通过定义共享测试的基类来实现。也许像这样的事情可以实现你的目标

// note: no [TestClass] on this type so it doesn't get discovered by MSTest.  
// Probably should also be abstract.
public class SharedTests<T> where T : IPlugin
{
    [TestMethod]
    public void NullLocalPluginContext()
    {
        XrmFakedContext context = new XrmFakedContext();

        Assert.ThrowsException<Exception>(
            () => context.ExecutePluginWith<T>(null));
    }
}
//注意:此类型上没有[TestClass],因此MSTest不会发现它。
//可能也应该是抽象的。
公共类共享测试,其中T:IPlugin
{
[测试方法]
public void NullLocalPluginContext()
{
XrmFakedContext context=新的XrmFakedContext();
Assert.ThrowsException(
()=>context.ExecutePluginWith(null));
}
}
您的插件类将从此类继承:

[TestClass]
public class CheckDuplicateOrderTests : SharedTests<CheckDuplicateOrder>
{
    // NullLocalPluginContext test is inherited from the parent type
}

[TestClass]
public class SomeOtherPluginTests : SharedTests<SomeOtherPlugin>
{
    // Also has NullLocalPluginContext test inherited, but for testing SomeOtherPlugin
}
[TestClass]
公共类CheckDuplicateOrderTests:SharedTests
{
//NullLocalPluginContext测试从父类型继承
}
[测试类]
公共类SomeOtherPluginTests:SharedTests
{
//还继承了NullLocalPluginText测试,但用于测试其他插件
}

与普通类一样,您应该支持组合而不是继承。即使 尽管测试类不必遵循与普通类相同的规则和准则,但这并不意味着我们不能实现它们

所以,当您觉得您的测试类中有一些通用的功能时,您应该提取一些测试使用的类。对于普通的商务舱,你也会这么做,是吗

class CommonFunc 
{ 
    public static bool NullLocalPluginContext<T, TException>() where T: IPlugIn, TException : Exception
    {
        XrmFakedContext context = new XrmFakedContext();
        try { context.ExecutePluginWith<T>(null)) };
        catch (T e) { return true; }
        return false;
    }
}

[TestClass]
public class CheckDuplicateOrderTests
{
    [TestMethod]
    public void NullLocalPluginContext()
    {
        Assert.IsTrue(CommonFunc.NullLocalPluginContext<CheckDuplicateOrder, Exception>(null));
    }
}

[TestClass]
public class SomeOtherPluginTests
{
    [TestMethod]
    public void NullLocalPluginContext()
    {
        Assert.IsTrue(CommonFunc.NullLocalPluginContext<SomePlugin, InvalidPluginExecutionException>(null));
    }
}
类CommonFunc
{ 
public static bool nulllocalpluginotext(),其中T:IPlugIn,TException:Exception
{
XrmFakedContext context=新的XrmFakedContext();
尝试{context.ExecutePluginWith(null))};
catch(te){return true;}
返回false;
}
}
[测试类]
公共类CheckDuplicateOrderTests
{
[测试方法]
public void NullLocalPluginContext()
{
Assert.IsTrue(CommonFunc.NullLocalPluginContext(null));
}
}
[测试类]
公共类其他插件
{
[测试方法]
public void NullLocalPluginContext()
{
Assert.IsTrue(CommonFunc.NullLocalPluginContext(null));
}
}

如果您想记录在测试框架中抛出的实际异常,您还可以让您的常用方法重新抛出异常,而不是只返回
true
false

我不明白您的问题。您能否详细说明
上下文
某个插件
检查重复顺序
之间的关系?该映像根本没有帮助,因为它包含完全不同的类。@Houkouha您不应该在单元测试中使用类继承@当然,图片链接后的信息。上下文只是一个带有填充实体的假环境,在这里并不重要。我正在尝试编写类似于“child.target.class”的东西,而不是“someplugin”,但它不接受IPlugin抽象。@PWND我是否要将它隐藏在一个区域下,并在每个新创建的类之后复制粘贴程序?@Houkouha,如您所愿。主要思想是单元测试,它是一个“单元”,应该是独立的。也许这被认为是滥用,但对此不确定。但是,从可维护性的角度来看,我并不喜欢这种方法,但我也不喜欢将代码复制N次(对于N>3的值)。在我的团队中,我们在测试中做了两件事,我们考虑的一些因素是代码被复制的次数、复制的次数,以及我们经常看到代码设计的变化受到的影响(真的,所有这些都是将来维护n个拷贝所需花费多少的指标)。所有这些考虑都导致了一个主观的结论……同意,务实的胜利。我也会有可读性作为一个因素,如果你找到的只是零代码和注释。。。小说读者很可能会感到困惑!
class CommonFunc 
{ 
    public static bool NullLocalPluginContext<T, TException>() where T: IPlugIn, TException : Exception
    {
        XrmFakedContext context = new XrmFakedContext();
        try { context.ExecutePluginWith<T>(null)) };
        catch (T e) { return true; }
        return false;
    }
}

[TestClass]
public class CheckDuplicateOrderTests
{
    [TestMethod]
    public void NullLocalPluginContext()
    {
        Assert.IsTrue(CommonFunc.NullLocalPluginContext<CheckDuplicateOrder, Exception>(null));
    }
}

[TestClass]
public class SomeOtherPluginTests
{
    [TestMethod]
    public void NullLocalPluginContext()
    {
        Assert.IsTrue(CommonFunc.NullLocalPluginContext<SomePlugin, InvalidPluginExecutionException>(null));
    }
}