How do I mock code like this in my unit test. I'm using xUnit and Moq in asp.net core 5. I'm new to xUnit and Moq.
var url = configuration.GetSection("AppSettings").GetSection("SmsApi").Value;
The configuration object is already injected into the constructor.
This is what I currently have in my unit test class
public class UtilityTests
{
private readonly Utility sut;
public UtilityTests()
{
var mockConfig = new Mock<IConfiguration>();
var mockConfigSection = new Mock<IConfigurationSection>();
//mockConfigSection.Setup(x => x.Path).Returns("AppSettings");
mockConfigSection.Setup(x => x.Key).Returns("SmsApi");
mockConfigSection.Setup(x => x.Value).Returns("http://example.com");
mockConfig.Setup(x => x.GetSection("AppSettings")).Returns(mockConfigSection.Object);
sut = new Utility(mockConfig.Object);
}
[Fact]
public void SendSmsShdReturnTrue()
{
var fixture = new Fixture();
var result = sut.SendSms(fixture.Create<string>(), fixture.Create<string>());
result.Should().BeTrue();
}
}
Alternative approach tp introduce a class to represent section of the configuration, then use IOptions
interface to inject it to the constructor.
Your tests then become simple to configure without mocking, just create an instance and pass it to the constructor.
Something like below:
class SmsApiSettings
{
public string Url { get; set; }
}
Register during startup
services.Configure<SmsApiSettings>(Configuration.GetSection("SmsApi"));
Constructor
public class ClassUnderTest
{
private readonly SmsApiSettings _smsApiSettings;
public ClassUnderTest(IOptions<> smsOptions)
{
_smsApiSettings = smsOptions.Value;
}
}
Tests
var settings = new SmsApiSettings { Url = "http://dummy.com" };
var options = Options.Create(settings);
var sut = new ClassUnderTest(options);
Enjoy happy life without mocks ;)