I haven't written any Azure functions in quite a long time, and thought I'd refresh myself today, but I've clearly forgotten how to write appropriate unit tests for them. I have the following Function - it picks a random quote from a list;
public class QuoteFunction
{
private readonly IQuoteBank _repository;
public QuoteFunction(IQuoteBank repository)
{
_repository = repository;
}
[FunctionName("GetQuote")]
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
Quote quote = _repository.getQuote();
return new OkObjectResult(quote);
}
}
and it uses dependency injection to obtain the list of quotes - I have the following in Startup;
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddSingleton<IQuoteBank, QuoteBank>();
builder.Services.AddLogging();
}
which is injected into the constructor of the Function. as shown in the first snippet.
What I am struggling with is how I can use Moq to force the quote (which is randomly selected) to be consistent. I know I can mock the Interface IQuoteBank - but there is no where I can pass this mock object into the Run method.
So what I want to know is how I can pass a mock object to make the same quote be produced for unit testing? Has anyone done anything like this before? any examples in github?
I'm pretty sure I did a few years ago, just cant remember at all.
CodePudding user response:
Setup the mock and pass that into the subject under test via constructor injection.
public async Task MyTestMehod() {
// Arrange
Mock<IQuoteBank> mock = new Mock<IQuoteBank>();
mock.Setup(_ => _.getQuote()).Returns("my consistent quote here")
var subject = new QuoteFunction(mock.Object);
//Act
IActionResult result = await subject.Run(Mock.Of<HttpRequest>(), Mock.Of<ILogger>());
//Assert
// ... assert my expected behavior
}