This is the first time I am writing test case and I am not sort of stuck and not sure how to proceed further.
I have the following API. In the below sample I have 2 endpoints which I want to perform testing.
public class ValuesController : Controller
{
//This interface is used to setup dynamo db and connection to aws
private IDynamoDbClientInitialization _clientAccessor;
private static string dynamoDbTable = string.Empty;
public ValuesController(IOptions<Dictionary<string, string>> appSettings, IDynamoDbClientInitialization clientAccessor)
{
var vals = appSettings.Value;
dynamoDbTable = vals["dynamoDbTable"];
_clientAccessor = clientAccessor;
}
[HttpGet("api/data")]
public async Task<List<MyModel>> GetAllData(string type, string status)
{
List<ScanCondition> conditions = new List<ScanCondition>();
conditions.Add(new ScanCondition("Type", ScanOperator.Equal, type));
conditions.Add(new ScanCondition("Status", ScanOperator.Equal, status));
var response = await _clientAccessor.GetContext().ScanAsync<MyModel>(conditions, AWSHelperMethods.GetDynamoDbOperationConfig(dynamoDbTable)).GetRemainingAsync();
return results.Select(x => x.UpdatedBy.ToLower()).ToList();
}
[HttpPost("api/save")]
public async Task<IActionResult> SaveData([FromBody] List<MyModel> listData, string input, string name, string type)
{
List<MyModel> model = null;
foreach (var data in listData)
{
//populating data here
await _clientAccessor.GetContext().SaveAsync(data, AWSHelperMethods.GetDynamoDbOperationConfig(dynamoDbTable));
}
return Ok();
}
}
public class DynamoDbClientInitialization : IDynamoDbClientInitialization
{
private readonly DynamoDbClientSettings settings;
private DynamoDBContext _awsContext;
public DynamoDbClientInitialization(IOptions<DynamoDbClientSettings> options)
{
settings = options?.Value;
}
public DynamoDBContext GetContext()
{
//Check is context already exists. If not create a new one.
if(_awsContext != null)
{
return _awsContext;
}
else
{
var creds = AWSHelperMethods.SetAwsCredentials(settings.Id, settings.Password);
var dynamoClient = AWSHelperMethods.GetDynamoDbClient(creds, settings.Region);
_awsContext = AWSHelperMethods.GetDynamoDbContext(dynamoClient);
return _awsContext;
}
}
}
public static class AWSHelperMethods
{
public static BasicAWSCredentials SetAwsCredentials(string awsId, string awsPassword)
{
var creds = new BasicAWSCredentials(awsId, awsPassword);
return creds;
}
public static AmazonDynamoDBClient GetDynamoDbClient(BasicAWSCredentials creds, RegionEndpoint awsDynamoDbRegion)
{
var client = new AmazonDynamoDBClient(creds, awsDynamoDbRegion);
return client;
}
public static DynamoDBContext GetDynamoDbContext(AmazonDynamoDBClient client)
{
var context = new DynamoDBContext(client);
return context;
}
public static DynamoDBOperationConfig GetDynamoDbOperationConfig(string dynamoDbTable)
{
DynamoDBOperationConfig config = new DynamoDBOperationConfig() { OverrideTableName = dynamoDbTable };
return config;
}
}
Below is the xUnit project that I added. Here I am using Moq to mock up my AWS connection and others. Questions are below in comments against the code.
public class DataTest
{
[Fact]
public void PassingTest()
{
//Arrange
var dynamoDbTable = "someValue";
//Trying to moq IOptions
var moqOp = new Mock<IOptions<Dictionary<string, string>>>();
//Create an instance to hold desired values
var vals = new Dictionary<string, string>();
//Set expected value
vals["dynamoDbTable"] = dynamoDbTable;
//Setup dependency behavior
moqOp.Setup(_ => _.Value).Returns(vals);
//Trying to moq my connection
var moqDb = new Mock<IDynamoDbClientInitialization>();
//Fake data
List<MyModel> data = new List<MyModel>()
{
//populate as needed
};
moqDb
.Setup(_ => _.GetContext().ScanAsync<MyModel>
(It.IsAny<List<ScanCondition>>(), AWSHelperMethods.GetDynamoDbOperationConfig(dynamoDbTable)).GetRemainingAsync())
.ReturnsAsync(data);
ValuesController controller = new ValuesController(moqOp.Object,
moqDb.Object);
var actual = controller.GetAllData();
}
}
Above I am getting the error as: An expression tree may not contain a call or invocation that uses optional arguments
This is on line
.Setup(_ => _.GetContext().ScanAsync<MyModel>
(It.IsAny<List<ScanCondition>>(), AWSHelperMethods.GetDynamoDbOperationConfig(dynamoDbTable)).GetRemainingAsync())
That's a lot of code to look at.
What's the definition of .GetRemainingAsync()? Could it be that it has optional parameters (possibly a CancellationToken?) If so, try specifying explicit values even for those optional parameters (e.g. default(CancellationToken)).
P.S.: This issue tracker is mainly for Moq bug reports, feature requests, and the like (i.e. its targeted at the further development of Moq). You might be better off asking usage questions on sites like Stack Overflow, as there'll be more people seeing your question.
I dint get usefull response in stackoverlfow so posted here. Where do I need to set CancellationToken. Can you share the example line.
Re-read my first post. I was referring to the last line of code you posted in your question.
Most helpful comment
That's a lot of code to look at.
What's the definition of
.GetRemainingAsync()? Could it be that it has optional parameters (possibly aCancellationToken?) If so, try specifying explicit values even for those optional parameters (e.g.default(CancellationToken)).