title: How do I unit test that a file uploads to Amazon S3 in my C# project?
body: <p>I've started writing unit tests for an Amazon S3 container for files.  I've never written tests for S3 before and I want to assert that a file is uploaded or at the very least the upload method for S3 is called.</p>
  <p>So, all I'm attempting to do is unit test a method that uploads a file to an S3 container.  Here is the test I have written so far to handle this.</p>
  <p>Note: I am using <a href="https://nsubstitute.github.io/" rel="nofollow noreferrer">NSubstitue</a> for mocking in my tests.</p>
  <pre><code>using Amazon.S3;
  using Amazon.S3.Model;
  using Amazon.S3.Transfer;
  using AmazonStorage.Repositories;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using NSubstitute;
  using System;
  using System.IO;
  using System.Threading;
  using System.Threading.Tasks;
  
  namespace AmazonStorage.Tests.Repositories
  {
      [TestClass]
      public class FileRepositoryTests
      {
          private readonly FileRepository _sut;
          private readonly IAmazonS3 _client = Substitute.For&lt;IAmazonS3&gt;();
          private readonly TransferUtility _transfer = Substitute.For&lt;TransferUtility&gt;();
     
      public FileRepositoryTests()
      {
          var request = new GetObjectRequest()
          {
              Key = &quot;somefile.txt&quot;,
              BucketName = &quot;aws-s3-apadmi&quot;
          };
          _client.GetObjectAsync(request);
          _sut = new FileRepository(_client);
      }
  
      [TestMethod]        
      public async Task PutFileInStorage_ShouldReceieveCallToUploadAsyc()
      {   
          // Arrange
          await _transfer.UploadAsync(Arg.Any&lt;string&gt;(), Arg.Any&lt;string&gt;(), Arg.Any&lt;CancellationToken&gt;());
         
          //Assert
          // I was thinking of something like this?
          // await _client.Received(1).UploadObjectFromStreamAsync(Arg.Any&lt;string&gt;(), Arg.Any&lt;string&gt;(), Arg.Any&lt;Stream&gt;());
      }
  </code></pre>
  <p>As you'll see I define my system under test, I bring in and mock the IAmazonS3 interface, I also mock the <code>TransferUtility</code> which is typically called when you upload a file to S3.</p>
  <p>The <code>FileRepository</code> class has a file exists check which you'll see below in the method and that is why I pass the <code>GetObjectAsync</code> with a mocked <code>GetObjectRequest</code> into the <code>FileRepository</code>.</p>
  <p>Here is my method to upload a file to S3.</p>
  <pre><code>private readonly IAmazonS3 _client;
  
  public FileRepository(IAmazonS3 client)
  {
      _client = client;
  }
  
  public async Task PutFileInStorage(string fileName, string content)
  {      
      try
      {
          await UploadToS3(fileName, content);
      }
      catch (Exception ex)
      {
          throw new Exception(ex.Message);
      }
  }
   
  public async Task UploadToS3(string fileName, string content)
  {            
      using MemoryStream ms = new(Encoding.UTF8.GetBytes(content));
           
      var uploadRequest = new TransferUtilityUploadRequest
      {
          InputStream = ms,
          Key = fileName,
          BucketName = &quot;aws-s3-apadmi&quot;                    
      };
      
      bool fileCheck = await CheckFileExists(uploadRequest.Key, uploadRequest.BucketName);
      
      if (fileCheck.Equals(true))
              throw new Exception(&quot;File already exists&quot;);                
  
      if (!fileCheck)
      {
          // Upload file to storage
          try
          {
              var fileTransferUtility = new TransferUtility(_client);
              await fileTransferUtility.UploadAsync(uploadRequest);
          }
          catch (Exception ex)
          {
              throw new Exception(ex.Message);
          }
      }
  }
  </code></pre>
  <p>The question is, how do I assert that this file has uploaded or at the very least that the <code>UploadAsync</code> has been called once?</p>