public async Task QueueTrigger_WithNonTextualByteArrayMessageNotUsingQueueTriggerBindingData_DoesNotThrow()
        {
            try
            {
                // Arrange
                var host = new HostBuilder()
                           .ConfigureDefaultTestHost <QueueTriggerBindingDataProgram>(c =>
                {
                    c.AddAzureStorage();
                })
                           .Build()
                           .GetJobHost();

                using (host)
                {
                    MethodInfo        methodInfo    = typeof(QueueTriggerBindingDataProgram).GetMethod(nameof(QueueTriggerBindingDataProgram.ProcessQueueAsBytes));
                    byte[]            expectedBytes = new byte[] { 0x00, 0xFF }; // Not valid UTF-8
                    CloudQueueMessage message       = CloudQueueMessage.CreateCloudQueueMessageFromByteArray(expectedBytes);

                    // Act
                    await host.CallAsync(methodInfo, new { message = message });

                    // Assert
                    Assert.Equal(QueueTriggerBindingDataProgram.Bytes, expectedBytes);
                }
            }
            finally
            {
                QueueTriggerBindingDataProgram.QueueTrigger = null;
            }
        }
        public async Task QueueTrigger_WithTextualByteArrayMessage_ProvidesQueueTriggerBindingData()
        {
            try
            {
                // Arrange
                var host = new HostBuilder()
                           .ConfigureDefaultTestHost <QueueTriggerBindingDataProgram>(c =>
                {
                    c.AddAzureStorage();
                })
                           .Build()
                           .GetJobHost();

                using (host)
                {
                    MethodInfo        methodInfo      = typeof(QueueTriggerBindingDataProgram).GetMethod(nameof(QueueTriggerBindingDataProgram.OnQueue));
                    string            expectedMessage = "abc";
                    CloudQueueMessage message         = new CloudQueueMessage(expectedMessage);
                    Assert.Equal(expectedMessage, message.AsString); // Guard

                    // Act
                    await host.CallAsync(methodInfo, new { message });

                    // Assert
                    Assert.Equal(expectedMessage, QueueTriggerBindingDataProgram.QueueTrigger);
                }
            }
            finally
            {
                QueueTriggerBindingDataProgram.QueueTrigger = null;
            }
        }
        public async Task QueueTrigger_WithNonTextualByteArrayMessageUsingQueueTriggerBindingData_Throws()
        {
            try
            {
                // Arrange
                var host = new HostBuilder()
                           .ConfigureDefaultTestHost <QueueTriggerBindingDataProgram>(c =>
                {
                    c.AddAzureStorage();
                })
                           .Build()
                           .GetJobHost();

                using (host)
                {
                    MethodInfo        methodInfo = typeof(QueueTriggerBindingDataProgram).GetMethod(nameof(QueueTriggerBindingDataProgram.OnQueue));
                    byte[]            contents   = new byte[] { 0x00, 0xFF }; // Not valid UTF-8
                    CloudQueueMessage message    = CloudQueueMessage.CreateCloudQueueMessageFromByteArray(contents);

                    // Act & Assert
                    FunctionInvocationException exception = await Assert.ThrowsAsync <FunctionInvocationException>(
                        () => host.CallAsync(methodInfo, new { message = message }));

                    // This exeption shape/message could be better, but it's meets a minimum acceptibility threshold.
                    Assert.Equal("Exception binding parameter 'queueTrigger'", exception.InnerException.Message);
                    Exception innerException = exception.InnerException.InnerException;
                    Assert.IsType <InvalidOperationException>(innerException);
                    Assert.Equal("Binding data does not contain expected value 'queueTrigger'.", innerException.Message);
                }
            }
            finally
            {
                QueueTriggerBindingDataProgram.QueueTrigger = null;
            }
        }
        public async Task BlobTrigger_ProvidesBlobTriggerBindingData()
        {
            try
            {
                // Arrange
                var host = new HostBuilder()
                           .ConfigureDefaultTestHost <BlobTriggerBindingDataProgram>(c =>
                {
                    c.AddAzureStorage();
                })
                           .Build()
                           .GetJobHost();

                using (host)
                {
                    CloudStorageAccount account = CloudStorageAccount.DevelopmentStorageAccount;

                    MethodInfo         methodInfo    = typeof(BlobTriggerBindingDataProgram).GetMethod(nameof(BlobTriggerBindingDataProgram.OnBlob));
                    string             containerName = "a";
                    string             blobName      = "b";
                    string             expectedPath  = containerName + "/" + blobName;
                    CloudBlobContainer container     = account.CreateCloudBlobClient().GetContainerReference(containerName);
                    ICloudBlob         blob          = container.GetBlockBlobReference(blobName);

                    // Act
                    await host.CallAsync(methodInfo, new { blob = blob });

                    // Assert
                    Assert.Equal(expectedPath, BlobTriggerBindingDataProgram.BlobTrigger);
                }
            }
            finally
            {
                BlobTriggerBindingDataProgram.BlobTrigger = null;
            }
        }