Skip to content

Instantly share code, notes, and snippets.

@Adam--
Last active February 14, 2021 13:58
Show Gist options
  • Save Adam--/b503168e4f568658a172c25dc98b53a8 to your computer and use it in GitHub Desktop.
Save Adam--/b503168e4f568658a172c25dc98b53a8 to your computer and use it in GitHub Desktop.
Testing CloudTable dependent code using the Azure Storage Emulator and NUnit
public class TestingCloudTableWithAzureStorageEmulator
{
private CloudTableClient developmentCloudTableClient;
private CloudTable emulatedCloudTable;
[OneTimeSetUp]
public void OneTimeSetUp()
{
var azureStorageEmulatorProcess = Process.Start("C:\\Program Files (x86)\\Microsoft SDKs\\Azure\\Storage Emulator\\AzureStorageEmulator.exe", "start");
azureStorageEmulatorProcess?.WaitForExit(2000);
this.developmentCloudTableClient = CloudStorageAccount.DevelopmentStorageAccount.CreateCloudTableClient();
}
[OneTimeTearDown]
public void OneTimeTearDown()
{
var azureStorageEmulatorProcess = Process.Start("C:\\Program Files (x86)\\Microsoft SDKs\\Azure\\Storage Emulator\\AzureStorageEmulator.exe", "stop");
azureStorageEmulatorProcess?.WaitForExit(2000);
}
[SetUp]
public void SetUp()
{
this.emulatedCloudTable = this.developmentCloudTableClient.GetTableReference("unittests");
if (this.emulatedCloudTable.Exists())
{
this.emulatedCloudTable.Delete();
}
this.emulatedCloudTable.Create();
}
[TearDown]
public void TearDown()
{
this.emulatedCloudTable.Delete();
}
}
@agporsch
Copy link

Screen-Shot-2014-12-05-at-8 57 26-AM

@Adam--
Copy link
Author

Adam-- commented Feb 14, 2020

Thanks for creating and linking a gist! I'm sure someone may find it helpful in the future if they stumble upon this gist and conversation.

I linked to the Classical and Mockist Testing section of the Mocks Aren't Stubs article because it was the first easy to reference article that came to mind that described that there are different mindsets with unit testing. One mindset being to use real objects where ever possible. This mindset is different than how you and I both approach unit testing and while we see fallacies and faults in it, it isn't necessarily wrong. And no, I don't mean to imply that you find it wrong. I could see this conversation going very differently with someone who didn't really care about these nuances. I suppose they would argue on pedanticism or that an emulated db is nothing more than an elaborate test double.

To me, I consider gists a step up from personal notes and have always treated them as such. Below is roughly the order in which I would be concerned with how accurate something is given their various mediums with some links that I found with the most casual of searching (also I'm shocked to see my gist as the 2nd result on my google search, but I suppose these results have been tailored to me).
I have to say though that this interaction has made me reconsider how people may consume gists.

  1. Source repositories (Azure/azure-storage-net#465)
  2. Documentation and books
  3. Blog posts (https://social.technet.microsoft.com/wiki/contents/articles/35320.faking-out-azure-unit-testing-with-microsoft-fakes.aspx)
  4. Example repositories
  5. SO answers (https://stackoverflow.com/questions/53510000/mocking-cloudstorageaccount-and-cloudtable-for-azure-table-storage)
  6. Gists

Shouldn't we call out publicly available information that is wrong or misleading and try to have it corrected in some way, even if you do it clumsily, as it appears I have? I think so

I suppose I would try if it affected me as it has you. I don't think that I would have approached this instance the same way you did though. Rather, I would have found a solution that fit better and offered it up in the comments. My comment would probably be something along the lines of, "This seems to be more of an integration test rather than a unit test since it using a real CloudTable. I see that this was written quite a bit of time ago, but it looks like the CloudTable members are now marked virtual so you can mock it (Azure/azure-storage-net#465). I've done this successfully with Moq/NSubstitute, you can check it out here [link]"

To clarify, the exaggeration, wasted time, and blame shift comments were prompted by my interpretation of your comment "if this was correctly labelled he might well have saved himself some time and effort, but also he'd have been able to create the integration tests required too at the same time". Thanks for clarifying your intent, I appreciate it.

@spettifer
Copy link

Certainly prompted a good discussion even if approached awkwardly (and you're right, it was by me). I know what you mean about Google - I asked an SO question recently and within 25 hours it was too five in Google for the search terms I was using but as you say, it does get tailored. As a result of all this I have begins to be more careful about how I refer to test objects which is a good thing. It's very easy to fall into bad habits and I certainly had by using terms that have been misappropriated and anything that makes you stop and re-evaluate how you are using language to communicate ideas and concepts is a good thing. Thanks for the discussion. Oh, and I will be a bit more careful about checking the age of stuff before opening my mouth in future 😁

@viviandeveloper
Copy link

Very interesting discussion and something I've been thinking about how best to test an Azure function with a table binding. I had thought about an approach similar to what's in this gist relying on Azure Storage Emulator but I felt it's not isolated and repeatable enough. Fortunately CloudTableClient exposes a DelegatingHandler property which you can assign a stub handler to providing the JSON response that would come back from the storage account.

Here is an example of how it works https://gist.github.com/vivianroberts/4bf161fdd6a9692d202888130e84df6b

To get the structure of the responses I use Azure Cli with the AZURE_STORAGE_CONNECTION_STRING environment variable set to "UseDevelopmentStorage=true" and then set up a proxy in Postman on 10002 to capture the requests. Next I switch off the proxy and start Azure Storage Emulator and fire the captured requests from Postman to get the response body.

Hopefully this approach provides a good balance between all the suggestions in this discussion 😊

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment