【问题标题】:How can I set a generic parameter in the moq setup?如何在MoQ设置中设置一般参数?
【发布时间】:2020-06-12 15:54:13
【问题描述】:

我正在尝试使用 MOQ 设置具有通用功能的模拟接口。该函数具有以下符号:

public interface IWizard
{
    bool Cast<TSpell>(TSpell spell)
        where TSpell : SpellBase, IComponents;
}

当我尝试设置设置功能时,我似乎无法以直接的方式完成它。我不断收到消息,说不可能进行隐式转换。它包含以下文本:'没有从 'SpellBase' 到 'IComponents' 的隐式引用转换。

var wizard = new Mock<IWizard>();
wizard
    .Setup(x => x.Cast(It.IsAny<SpellBase>())) // this line has an error
    .Returns(true);

除了实现同时实现SpellBaseIComponents 的基类之外,我还有哪些选择?这甚至可能吗?

编辑1: 我尝试通过以下方式实现 Piotr 的方法:

    [Test]
    public void Test_JsonConvert_Performace()
    {
        var wizard = new Mock<IWizard>();
        wizard
            .Setup(x => x.Cast(It.IsAny<TestSpell>()))
            .Returns(true);


        var result = wizard.Object.Cast(new RealSpell());

        Assert.IsTrue(result);

    }


    public interface IWizard
    {
        bool Cast<TSpell>(TSpell spell)
            where TSpell : SpellBase, IComponents;
    }


    public abstract class SpellBase
    {
    }

    public interface IComponents
    {
    }

    public class TestSpell : SpellBase, IComponents
    {
    }

    public class RealSpell : SpellBase, IComponents
    {
    }

很遗憾我的测试失败了。

【问题讨论】:

    标签: c# unit-testing generics moq


    【解决方案1】:

    您可以使用通用方法创建模拟:

    [TestMethod]
    void Test()
    {
        var wizard = MockObject<TestSpell>();
    }
    
    private Mock<IWizard> MockObject<T>() where T : SpellBase, IComponents
    {
        var mock = new Mock<IWizard>();
        mock.Setup(pa => pa.Cast(It.IsAny<T>()))
            .Returns(true);
        return mock;
    }
    
    private class TestSpell : SpellBase, IComponents
    { }
    

    TestSpell 类仅在您的测试项目中是必需的

    【讨论】:

    • 不幸的是,这只有在我知道我正在使用的类型时才有效,而我不知道
    【解决方案2】:

    拳头选项: 您需要从 IWizard.Cast 约束中删除 IComponent

    public interface IWizard
    {
        bool Cast<TSpell>(TSpell spell) where TSpell : SpellBase, IComponents;//wont compile
    
        bool Cast<TSpell>(TSpell spell) where TSpell : SpellBase; //will compile
    }
    

    第二种选择:创建一个继承SpellBase并实现IComponents的类

    public class ComponetsSpellBase:SpellBase, IComponents
    {
        //IComponents Implementation
    }
    
    
    wizard.Setup(x => x.Cast(It.IsAny<ComponetsSpellBase>())).Returns(false);
    
    public class FireSpell:ComponentSpellBase{}
    

    【讨论】:

    • 函数 Cast 缺少泛型类的 IComponents 接口实现。
    • 这不会为我编译
    • 你的 SpellBase 是否实现了 IComponents?
    • 没有,虽然这样做可以解决我的问题,但这不是我目前可以采取的行动
    猜你喜欢
    • 1970-01-01
    • 2011-05-04
    • 1970-01-01
    • 1970-01-01
    • 2013-06-15
    • 1970-01-01
    • 2019-03-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多