Moq ruft bei der Setup-Funktion die Basisklasse anstelle der geerbten Klasse aufC#

Ein Treffpunkt für C#-Programmierer
Guest
 Moq ruft bei der Setup-Funktion die Basisklasse anstelle der geerbten Klasse auf

Post by Guest »

Ich erstelle einen C#-Hintergrunddienst mit der folgenden Definition

Code: Select all

public class SqsBackgroundService(
IPollingConfiguration pollingSettings,
IServiceProvider serviceProvider,
IMessagingService messagingService,
IOptions options,
ILogger logger) : RecurringBackgroundService(pollingSettings, serviceProvider)
where TConfig : QueueConfiguration
where TProcessor : IMessageProcessor
{
internal override async Task Execute(IServiceProvider provider, CancellationToken cancellationToken)
{
using (var scope = provider.CreateScope())
{
var messageProcessor = scope.ServiceProvider.GetService();

if (messageProcessor == null)
{
throw new NullReferenceException("Unable to resolve message processor");
}

var result = await messageProcessor.ProcessMessage(message, token);
if (result.ProcessSuccessfully)
....
}
}
}
}
Dies wird von einem Listener verwendet

Code: Select all

public class ClientEntityListener(
IServiceProvider serviceProvider,
IOptions backgroundConfig,
IOptions queueConfig,
ILogger logger) :
SqsBackgroundService(
backgroundConfig.Value.ClientEntityPollingConfiguration,
serviceProvider,
serviceProvider.GetRequiredService(),
queueConfig,
logger)
{
}

Code: Select all

IClientEntityProcessor
erbt eine Basisklasse IMessageProcessor, die der erwartete TProcessor-Wert im SqsBackgroundService ist. Der Test wird wie folgt aufgebaut und aufgerufen.

Code: Select all

        var mockServiceProvider = new Mock();
var mockServiceScope = new Mock();
mockServiceScope.Setup(x => x.ServiceProvider).Returns(mockServiceProvider.Object);

var mockServiceScopeFactory = new Mock();
mockServiceScopeFactory
.Setup(x => x.CreateScope())
.Returns(mockServiceScope.Object);

mockServiceProvider
.Setup(x => x.GetService(typeof(IServiceScopeFactory)))
.Returns(mockServiceScopeFactory.Object);

....

var messageResult = new MessageResult(true);
var mockClientEntityProcessor = new Mock();
mockClientEntityProcessor.Setup(x => x.ProcessMessage(
It.IsAny(),
It.IsAny()))
.ReturnsAsync(messageResult);

mockServiceProvider
.Setup(x => x.GetService(typeof(IClientEntityProcessor)))
.Returns(mockClientEntityProcessor.Object);

....

var service = new ClientEntityListener(
mockServiceProvider.Object,
_mockBackgroundConfig.Object,
_mockQueueConfig.Object,
mockBaseLogger.Object);

await service.Execute(mockServiceProvider.Object, CancellationToken.None);

Wenn dieser Test ausgeführt wird, wird die Zeile

Code: Select all

var result = await messageProcessor.ProcessMessage(message, token);
im SqsBackgroundService gibt null anstelle des erwarteten messageResult zurück. Ich kann unter den Scheinaufrufen sehen, dass IMessageProcessor.ProcessMessage aufgerufen wird. Wenn ich jedoch im Test-Setup dieselben Zeilen ausführe, sind diese

Code: Select all

 var scope = mockServiceProvider.Object.CreateScope();
var processor = scope.ServiceProvider.GetService();
var test = await processor.ProcessMessage(messages[0], CancellationToken.None);
Ich kann sehen, dass das Ergebnis wie erwartet das messageResult ist, der Aufruf auf dem Mock ist jedoch IClientEntityProcessor.ProcessMessage. Dies lässt mich vermuten, dass das Problem darin besteht, dass die Basismethode von IMessageProcessor.ProcessMessage aufgerufen wird, die im aktuellen Setup nicht verspottet wird. Meine Versuche, den aufgerufenen IMessageProcessor zu verspotten, sind fehlgeschlagen. Gibt es eine Möglichkeit, dies zu verspotten, um die erwartete Leistung zu erbringen?

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post