How to write repository unit tests with respect to Cosmos database(SQLApi + CosmosClient)

Viewed 5010

I have a class as below :

 public class CosmosRepository: ICosmosRepository
 {
        private ICosmoDBSettings cosmoDbSettings;

        private CosmosClient cosmosClient;

        private static readonly object syncLock = new object();

        // The database we will create
        private Database database;

        public CosmosRepository(ICosmoDBSettings cosmoDBSettings)
        {
            this.cosmoDbSettings = cosmoDBSettings;

            this.InitializeComponents();
        }

        private void InitializeComponents()
        {
            try
            {
                if (cosmosClient != null)
                {
                    return;
                }

                lock (syncLock)
                {
                    if (cosmosClient != null)
                    {
                        return;
                    }

                    this.cosmosClient = new CosmosClient(
                        cosmoDbSettings.CosmosDbUri
                        , cosmoDbSettings.CosmosDbAuthKey
                        , new CosmosClientOptions
                            {
                                ConnectionMode = ConnectionMode.Direct
                            }
                        );
                    this.database = this.cosmosClient.CreateDatabaseIfNotExistsAsync(cosmoDbSettings.DocumentDbDataBaseName).Result;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }

I have my repository method as:
Don't bother about hardcoded values.

  public async Task<Employee> GetById()
    {
       var container = this.database.GetContainer("Employees");
       var document = await container.ReadItemAsync<Employee>("44A85B9E-2522-4BDB-891A- 
                      9EA91F6D4CBF", new PartitionKey("PartitionKeyValue"));
       return document.Response;
    }

Note
How to write Unit Test(MS Unit tests) in .NET Core with respect to Cosmos Database?
How to mock CosmosClient and all its methods. Could someone help me with this issue?

My UnitTests looks like:

public class UnitTest1
    {
        private Mock<ICosmoDBSettings> cosmoDbSettings;

        private Mock<CosmosClient> cosmosClient;

        private Mock<Database> database;

        [TestMethod]
        public async Task TestMethod()
        {
            this.CreateSubject();
            var databaseResponse = new Mock<DatabaseResponse>();
            var helper = new CosmosDBHelper(this.cosmoDbSettings.Object);
            this.cosmosClient.Setup(d => d.CreateDatabaseIfNotExistsAsync("TestDatabase", It.IsAny<int>(), It.IsAny<RequestOptions>(), It.IsAny<CancellationToken>())).ReturnsAsync(databaseResponse.Object);
            var mockContainer = new Mock<Container>();
            this.database.Setup(x => x.GetContainer(It.IsAny<string>())).Returns(mockContainer.Object);
            var mockItemResponse = new Mock<ItemResponse<PortalAccount>>();
            mockItemResponse.Setup(x => x.StatusCode).Returns(It.IsAny<HttpStatusCode>);
            var mockPortalAccount = new PortalAccount { PortalAccountGuid = Guid.NewGuid() };
            mockItemResponse.Setup(x => x.Resource).Returns(mockPortalAccount);
            mockContainer.Setup(c => c.ReadItemAsync<PortalAccount>(It.IsAny<string>(),It.IsAny<PartitionKey>(), It.IsAny<ItemRequestOptions>(), It.IsAny<CancellationToken>())).ReturnsAsync(mockItemResponse.Object);

            var pas = helper.GetById().Result;

            Assert.AreEqual(pas.PortalAccountGuid, mockPortalAccount.PortalAccountGuid);


        }
        public void CreateSubject(ICosmoDBSettings cosmoDBSettings = null)
        {
            this.cosmoDbSettings = cosmoDbSettings ?? new Mock<ICosmoDBSettings>();
            this.cosmoDbSettings.Setup(x => x.CosmosDbUri).Returns("https://localhost:8085/");
            this.cosmoDbSettings.Setup(x => x.CosmosDbAuthKey).Returns("C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==");
            this.cosmoDbSettings.Setup(x => x.DocumentDbDataBaseName).Returns("TestDatabase");
            this.database = new Mock<Database>();
            this.cosmosClient = new Mock<CosmosClient>();
        }
    }

Note: Exception: Response status code does not indicate success: 404 Substatus: 0 Reason: (Microsoft.Azure.Documents.DocumentClientException: Message: {"Errors":["Resource Not Found"]}

I'm not creating a document. directly I'm fetching the document because I'm returning the mock response only. Is it correct??

0 Answers
Related