public async Task DisposeAsync() { var eventName = "onMyCustomEvent"; var throttleInterval = 20; var projectionName = "mynamspace.something.somethingelse"; Func <Object, Task> callback = (x) => Task.Delay(10); var expectedProperties = new[] { "detail", "screenX", "screenY", "clientX", "clientY", "offsetX", "offsetY", "button", "buttons", "ctrlKey", "shiftKey", "altKey", "metaKey", "type" }; for (var i = 0; i < 10; i++) { var elementId = $"my-customer-dom-element-{i}"; _runtimeMock.Setup(x => x.InvokeAsync <Object>("mudThrottledEventManager.subscribe", It.Is <object[]>(z => z.Length == 7 && (string)z[0] == eventName && (string)z[1] == elementId && (string)z[2] == projectionName && (int)z[3] == throttleInterval && (Guid)z[4] != Guid.Empty && ContainsEqual((IEnumerable <string>)z[5], expectedProperties) == true && z[6] is DotNetObjectReference <EventListener> ))).ReturnsAsync(true); var result = await _service.Subscribe <MouseEventArgs>(eventName, elementId, projectionName, throttleInterval, callback); var flow = _runtimeMock.Setup(x => x.InvokeAsync <Object>("mudThrottledEventManager.unsubscribe", It.Is <object[]>(z => z.Length == 1 && (Guid)z[0] == result ))); if (i % 2 == 0) { flow.Throws(new InvalidOperationException("something went wrong! :(")); } else { flow.ReturnsAsync(true); } } await _service.DisposeAsync(); // a second time shouldn't change something await _service.DisposeAsync(); // a normal dispose shouldnt' change something _service.Dispose(); _runtimeMock.Verify(x => x.InvokeAsync <Object>("mudThrottledEventManager.subscribe", It.Is <object[]>(z => true )), Times.Exactly(10)); }