是否可以模拟“类型名称”?在c#中使用Moq模拟

本文关键字:模拟 Moq 类型名称 类型 是否 | 更新日期: 2023-09-27 18:17:45

我正在开发一个c#聊天机器人(基于。net Core),具有模块化的行为。我想开发的行为之一是一个"admin"模块,(在其他功能中)应该允许管理员通过名称动态启用或禁用其他行为。

我希望管理模块通过检查其类型信息和做类似的事情来确定行为的名称:

var name = behaviour.GetType().GetTypeInfo().Name.Replace("Behaviour", string.Empty).ToLowerInvariant();

在BDD规范中,我首先编写,我试图建立一个由管理模块(测试系统)和模拟行为组成的"行为链"。这些测试涉及发送命令,这些命令应导致管理模块启用或禁用模拟行为。

这是我到目前为止所做的:

public BehaviourIsEnabled() : base("Admin requests that a behaviour is enabled")
{
    var mockTypeInfo = new Mock<TypeInfo>();
    mockTypeInfo.SetupGet(it => it.Name).Returns("MockBehaviour");
    var mockType = new Mock<Type>();
    mockType.Setup(it => it.GetTypeInfo()).Returns(mockTypeInfo.Object);
    // TODO: make mock behaviour respond to "foo"
    var mockBehaviour = new Mock<IMofichanBehaviour>();
    mockBehaviour.Setup(b => b.GetType()).Returns(mockType.Object);
    this.Given(s => s.Given_Mofichan_is_configured_with_behaviour("administration"), AddBehaviourTemplate)
        .Given(s => s.Given_Mofichan_is_configured_with_behaviour(mockBehaviour.Object),
                "Given Mofichan is configured with a mock behaviour")
            .And(s => s.Given_Mofichan_is_running())
        .When(s => s.When_I_request_that_a_behaviour_is_enabled("mock"))
            .And(s => s.When_Mofichan_receives_a_message(this.JohnSmithUser, "foo"))
        .Then(s => s.Then_the_mock_behaviour_should_have_been_triggered())
        .TearDownWith(s => s.TearDown());
}

问题是,当我运行这是GetTypeInfo()Type上的扩展方法,所以Moq抛出异常:

Expression引用了一个不属于模拟对象的方法getypeinfo ()

另一种选择,我可以只是添加Name属性到IMofichanBehaviour,但我不喜欢在生产代码中添加任意方法/属性的想法,这只是为了测试代码的好处。

是否可以模拟“类型名称”?在c#中使用Moq模拟

用一个满足被嘲弄对象的假类来保持简单。

public class MockBehaviour : IMofichanBehaviour { ... }

然后test看起来像

public BehaviourIsEnabled() : base("Admin requests that a behaviour is enabled") {
    // TODO: make mock behaviour respond to "foo"
    var mockBehaviour = new MockBehaviour();

    this.Given(s => s.Given_Mofichan_is_configured_with_behaviour("administration"), AddBehaviourTemplate)
        .Given(s => s.Given_Mofichan_is_configured_with_behaviour(mockBehaviour),
                "Given Mofichan is configured with a mock behaviour")
            .And(s => s.Given_Mofichan_is_running())
        .When(s => s.When_I_request_that_a_behaviour_is_enabled("mock"))
            .And(s => s.When_Mofichan_receives_a_message(this.JohnSmithUser, "foo"))
        .Then(s => s.Then_the_mock_behaviour_should_have_been_triggered())
        .TearDownWith(s => s.TearDown());
}