我如何测试已注入LifetimeScope的Signal R集线器

问题描述 投票:0回答:2

如何编写单元测试来测试我的集线器?

这是我的中心班级:

public class MyHub : Hub
{
    private readonly ILifetimeScope _scope;
    private readonly IMyProvider _provider;

    public MyHub(ILifetimeScope scope)
    {
        scope = _scope;
        _provider = _scope.Resolve<IMyProvider>();
    }

    public void BroadcastMessage(int messageId)
    {
        var myMessage = _provider.GetFromDb(messageId);
        Clients.All.broadcastMessage(myMessage);
    }
}

我正在使用moq和xunit,我已经尝试过类似的事情:

//arrange
var messageId = 1;
var message = "test";
var providerMock = new Mock<IMyProvider>();
providerMock.Setup(x => x.GetFromDb(messageId).Returns(test);
var scopeMock = new Mock<ILifetimeScope>();
scopeMock.Setup(x => x.Resolve<IMyProvider>()).Returns(providerMock.Object);
var hub = new MyHub(scopeMock.Object);

//act
hub.BroadcastMessage(messageId);

//assert
providerMock.Verify(x => x.GetFromDb(messageId), Times.Once());

但是这会导致错误:

System.NotSupportedException:不支持的表达式:x => x.Resolve()扩展方法(此处为:ResolutionExtensions.Resolve)不能在设置/验证表达式中使用。

我找到了这个答案:https://stackoverflow.com/a/49523868/3708225说我可以做类似的事情

using (var mock = AutoMock.GetLoose()){
    var providerMock = new Mock<IMyPRovider>();
    providerMock.Setup(x=>x.GetFromDb(messageId)).Returns(message);
    mock.Provide(providerMock.Object);
    var lifetime = mock.Create<ILifetimeScope>();
    using (var scope = lifetimeScope.BeginLifetimeScope()){
        var innerMockProvider = scope.Resolve<IMyProvider>();
        //rest of test
    }
}

但是AutoMock.GetLoose().Provide()未定义

signalr moq autofac xunit
2个回答
0
投票

这可能不是您要寻找的答案。但是一种解决方法不是模拟生命周期范围,而是简单地设置一个autofac容器以在这些测试中使用。其次,您是否需要直接在您的班级中注入lifetimescope?也许使用装饰器模式,您可以让装饰器创建Lifetimescope并解析您的类并调用它。摆脱myhub类中的lifelifescope会使您的生活更轻松。使其他类的工作来控制Lifetimescope。否则,您将需要在所有其他类中重复此模式。您应该注入IMyProvider。


0
投票

这是我解决这个问题的方式:

如果我将集线器更改为以下内容:

public class MyHub : Hub
{

    private readonly <Func>IMyProvider _provider;

    public MyHub(<Func>IMyProvider provider)
    {
        _provider = provider;
    }

    public void BroadcastMessage(int messageId)
    {
        var provider = _provider();
        var myMessage = provider.GetFromDb(messageId);
        Clients.All.broadcastMessage(myMessage);
    }
}

现在我可以模拟Func<IMyProviider>以返回我需要的内容,而忽略生命周期范围

© www.soinside.com 2019 - 2024. All rights reserved.