Reputation: 97
I am trying to implement some unit/integration testing to an Azure v3 HTTP trigger and am running into some issues with the process.
I previously wrote some testing for an API controller that was using syntax like so:
TransactionResponse fakeResponse = new TransactionResponse { APIResponse = "Okay" };
var fakeSbus = A.Fake<IServiceBusPlatform>();
var fakeTransaction = A.Fake<ITransaction>();
A.CallTo(() => fakeTransaction.CreateTransaction(tran)).Returns(Task.FromResult(fakeResponse.APIResponse));
var controller = new SubmitController(fakeSbus, fakeTransaction);
var result = await controller._transaction.CreateTransaction(tran);
Assert.Equal(fakeResponse.APIResponse, result.ToString());
This worked fine because it was just testing a dbcontext and then asserting the return.
What I'm trying to do with the Azure function is evaluate the trigger based on the OkObjectResult but inside the function I have a few method calls and then logic that is dependant on the result of the method call. (returning a list, using a property of ListMember[0] to declare a var). Like so:
var BatchResults = await _dbService.RetrieveBatch(session);
var CompanyID = BatchResults[0].CompanyID;
Update: For a little more clarity here is the whole testing function:
var fakeBatch = new List<RetrievedBatch>();
fakeBatch.Add(new RetrievedBatch
{
CompanyID = new Guid(),
});
var testResponse = new OkObjectResult("OKAY");
var request = A.Fake<HttpRequest>();
request.Method = "POST";
byte[] byteArray = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(fakeTransaction));
MemoryStream stream = new MemoryStream(byteArray);
request.Body = stream;
var logger = A.Fake<ILogger>();
var fakeService = A.Fake<IDbService>();
A.CallTo(() => fakeService.RetrieveBatch(fakeTransaction)).Returns(fakeBatch);
var test = fakeService.RetrieveBatch(fakeTransaction);
var SM = new SessionManager(fakeService);
var response = await SM.Run(request, logger);
Oh and the method/type inside the interface is like this:
Task<List<RetrievedBatch>> RetrieveBatch(Transaction session);
The error is occurring inside SM.Run(x,y). After a bit of debugging I can see that the A.CallTo is returning the correct results inside of the testing function but when the Azure function is being run the value is not carried over, which is the code breaking issue.
Any help would be appreciated as I've spent far too much time trying to work this out and all the examples out there are basic and unfortunately not very helpful in this scenario.
Upvotes: 0
Views: 724
Reputation: 241714
I think the real problem is that fakeTransaction
isn't the same object inside the SM.Run
call as it is in the test. What class is it exactly? We don't have the definition of fakeTransaction
up above, but I see that you send a serialized representation of it into the request, not the original object.
So SM.Run
eventually calls fakeService.RetrieveBatch(Transaction session)
with a reconstituted session
object. What are the equality semantics of the Transaction
class? The configured Fake's RetrieveBatch
method will, as described in argument constraints, compare its input with fakeTransaction
using object.Equals
, and if it does not match, your configured behaviour will not be triggered.
If you're unsure about the equality semantics of Transaction
, consider reconstituting transaction from the byte array right in your test, and running object.Equals
on the two objects. That will show you whether they compare as equal.
If Transaction
turns out not to have value-based equality semantics, you will likely have to use one of the other argument constraint mechanisms, such as a custom matcher that examines the transaction's properties or maybe even ignore the actual value using A<Transaction>.Ignored
.
Upvotes: 1