Как проверить концентратор Signal R, в который встроен LifetimeScope - PullRequest
0 голосов
/ 10 апреля 2020

Как мне написать модульные тесты для проверки моего хаба?

Вот мой класс хаба:

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) могут не использоваться в выражениях настройки / проверки.

Я нашел этот ответ: { ссылка }, который говорит, что я могу сделать что-то вроде

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() не определен

Ответы [ 2 ]

1 голос
/ 12 апреля 2020

Вероятно, это не тот ответ, который вы ищете. Но обходной путь может заключаться не в том, чтобы имитировать время жизни, а просто в настройке контейнера autofa c для использования в этих тестах. Во-вторых, вам нужно вводить LifeScope непосредственно в вашем классе? Возможно, используйте шаблон декоратора, в котором вы позволяете декоратору создать жизненную область, разрешить ваш класс и вызвать его. Избавление от lifetimecope в вашем классе myhub сделает вашу жизнь проще. Сделайте работу другого класса для управления жизненным циклом. В противном случае вам нужно будет повторить этот шаблон и во всех других ваших классах. Вместо этого вы должны ввести IMyProvider.

0 голосов
/ 13 апреля 2020

Вот как я решил это:

Если я изменю свой концентратор на следующее:

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>, чтобы вернуть то, что мне нужно, и игнорировать время жизни сфера

...