Moq ruft bei der Setup-Funktion die Basisklasse anstelle der geerbten Klasse auf
Posted: 07 Jan 2025, 11:01
Ich erstelle einen C#-Hintergrunddienst mit der folgenden Definition
Dies wird von einem Listener verwendet
erbt eine Basisklasse IMessageProcessor, die der erwartete TProcessor-Wert im SqsBackgroundService ist. Der Test wird wie folgt aufgebaut und aufgerufen.
Wenn dieser Test ausgeführt wird, wird die Zeile
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
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?
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)
....
}
}
}
}
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
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);
Code: Select all
var result = await messageProcessor.ProcessMessage(message, token);
Code: Select all
var scope = mockServiceProvider.Object.CreateScope();
var processor = scope.ServiceProvider.GetService();
var test = await processor.ProcessMessage(messages[0], CancellationToken.None);