I am new to unit/integration testing, and to the .NET world.
Problem-1 : In one of the integration tests, I have to pass a (mock of) IConfiguration variable, which I currently build as
var mockConfig = GetConfiguration();
private static IConfiguration GetConfiguration() =>
new ConfigurationBuilder()
.SetBasePath($"{Directory.GetCurrentDirectory()})
.AddJsonFile("appSettings.json", true)
.AddCommonVariables()
.Build();
Trial-1: I have tried to do this
private static Mock<IConfiguration> GetConfiguration() =>
new Mock<IConfiguration>(new ConfigurationBuilder()
.SetBasePath($"{Directory.GetCurrentDirectory()})
.AddJsonFile("appSettings.json", true)
.AddCommonVariables()
.Build());
but, it exceptioned out with
Constructor arguments cannot be passed for interface mocks.
Trial-2: I tried to create with the Setup options of Moq
private static Mock<IConfiguration> GetMockConfiguration()
{
var _mockConfigurationBuilder = new Mock<ConfigurationBuilder>();
//How to setup these methods?
_mockConfigurationBuilder.Setup(x => x.SetBasePath(It.IsAny<String>())).Returns();
-_mockConfigurationBuilder.Setup(x => x.AddJsonFile()).Returns()
}
but I am not sure how to set up these methods.
Problem-2: Is to ultimately mock IDocumentClient, which I use to query my entities
_cosmosWrapper = new CosmosWrapper(mockLogger.Object, mockConfig.Object);
use it as
private readonly IDocumentClient _documentClient;
public CosmosWrapper(ILogger<CosmosWrapper> logger, IConfiguration config)
{
var cosmosConnectionSecretKey = config["cosmosSecretName"];
var cosmosConnectionString = config[cosmosConnectionSecretKey];
var cosmosInfo = ConnectionStringParser.Parse(cosmosConnectionString);
_documentClient = new DocumentClient(new Uri(cosmosInfo["AccountEndpoint"]), cosmosInfo["AccountKey"]);
}
Update:
I had to refactor the setup of document client, by creating a cosmos connection class.
And the setup for mock - cosmos connection was,
var cosmosConnection = new Mock<ICosmosConnection>();
cosmosConnection.Setup(c => c.CosmosInfo)
.Returns(new Dictionary<string, string>(new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("AccountEndpoint", "//string1.string2")
}));
And finally for mocking the document client, I took ideas from How to (should I) mock DocumentClient for DocumentDb unit testing?
and implemented few more helper methods, for my needs.
private static void SetupProvider(Mock<IFakeDocumentQuery<MyClass>> mockDocumentQuery,
Mock<IQueryProvider> provider)
{
provider.Setup(p => p.CreateQuery<MyClass>(It.IsAny<Expression>())).Returns(mockDocumentQuery.Object);
mockDocumentQuery.As<IQueryable<MyClass>>().Setup(x => x.Provider).Returns(provider.Object);
}
and
private static void SetupMockForGettingEntities(Mock<IDocumentClient> mockDocumentClient,
IMock<IFakeDocumentQuery<MyClass>> mockDocumentQuery)
{
mockDocumentClient.Setup(c => c.CreateDocumentQuery<MyClass>(It.IsAny<Uri>(), It.IsAny<FeedOptions>()))
.Returns(mockDocumentQuery.Object);
}