In Abp framework, I'm trying to write a test for my FamilyAppService class (see below). I need to mock an IAutho instance in the constructor of the FamilyAppService. I tried mocking the IAutho then adding it to a new instance of FamilyAppService (instead of using GetRequiredService()) but I get a 'System.ArgumentNullException' error with the ObjectMapper.
FamilyAppService Class
public class FamilyAppService : KmAppService, IFamilyAppService {
private readonly IAutho autho;
public FamilyAppService(
IAutho autho) {
this.autho = autho;
}
public virtual async Task SendRequest(SendRequestInput input) {
var family = ObjectMapper.Map<FamilyDto, Family>(input.Family);
// code ...
await autho.FindUserIdByEmail(family.Email);
}
}
Autho Class. I need to substitute the IAutho dependence with a Mocked class using nSubstitute
public class Autho : IAutho, ITransientDependency {
public Autho( ) {
}
public virtual async Task<User> FindUserIdByEmail(string input) {
// Don’t want this code touched in test
// Code ...
}
}
My current test...
[Fact]
public async Task ShouldSendEmail() {
var autho = Substitute.For<IAutho>();
autho.FindUserIdByEmail(Arg.Any<string>()).Returns((User)null);
var familyAppService = new FamilyAppService(autho);
// var familyAppService = GetRequiredService<IFamilyAppService>();
// setup input code here..
// get ObjectMapper error here
await familyAppService.SendRequest(input);
// Assert
}
A member from the github abp repo gave me the correct answer. You need to override the AfterAddApplication Method on the test class and add the substitue/mock to services.AddSingletone.
Example...
protected override void AfterAddApplication(IServiceCollection services) {
var autho = Substitute.For<IAutho>();
autho.FindUserIdByEmail(Arg.Any<string>()).Returns((User)null);
services.AddSingleton(autho);
}