// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information. using System.Threading; using Moq; using Xunit; using Assert = Microsoft.TestCommon.AssertEx; namespace System.Web.Mvc.Async.Test { public class SynchronizationContextUtilTest { [Fact] public void SyncWithAction() { // Arrange bool actionWasCalled = false; bool sendWasCalled = false; Mock mockSyncContext = new Mock(); mockSyncContext .Setup(sc => sc.Send(It.IsAny(), null)) .Callback( delegate(SendOrPostCallback d, object state) { sendWasCalled = true; d(state); }); // Act SynchronizationContextUtil.Sync(mockSyncContext.Object, () => { actionWasCalled = true; }); // Assert Assert.True(actionWasCalled); Assert.True(sendWasCalled); } [Fact] public void SyncWithActionCapturesException() { // Arrange InvalidOperationException exception = new InvalidOperationException("Some exception text."); Mock mockSyncContext = new Mock(); mockSyncContext .Setup(sc => sc.Send(It.IsAny(), null)) .Callback( delegate(SendOrPostCallback d, object state) { try { d(state); } catch { // swallow exceptions, just like AspNetSynchronizationContext } }); // Act & assert SynchronousOperationException thrownException = Assert.Throws( delegate { SynchronizationContextUtil.Sync(mockSyncContext.Object, () => { throw exception; }); }, @"An operation that crossed a synchronization context failed. See the inner exception for more information."); Assert.Equal(exception, thrownException.InnerException); } [Fact] public void SyncWithFunc() { // Arrange bool sendWasCalled = false; Mock mockSyncContext = new Mock(); mockSyncContext .Setup(sc => sc.Send(It.IsAny(), null)) .Callback( delegate(SendOrPostCallback d, object state) { sendWasCalled = true; d(state); }); // Act int retVal = SynchronizationContextUtil.Sync(mockSyncContext.Object, () => 42); // Assert Assert.Equal(42, retVal); Assert.True(sendWasCalled); } } }