Mock virtual methods and not mock overridden of this methods with Moq - unit-testing

In the below code I want to mock DB operation of GetTitle(int id) in FooBase class. But I want to test validations part in overridden GetTitle(int id).
I want to test overridden method but mock the base method
How I can mock virtual method and testing the overridden of it?
public abstract class FooBase
{
public virtual string GetTitle(int id) { return "Title From DB" /*Select From DB*/; }
}
public class Foo : FooBase
{
public override string GetTitle(int id)
{
if (id < 0)
return "Invalid id";
/*Doing somethings like other validations and etc*/
return $"Valid ID ({base.GetTitle(id)})";
}
}
public class FooTests
{
[Fact]
public void GetTitle() // Fails
{
// Arrange
var expectedID = 1;
var expectedResult = "Test";
var fooMock = new Mock<Foo>();
fooMock.Setup(x => x.GetTitle(It.IsAny<int>())).Returns(expectedResult);
var foo = fooMock.Object;
// Act
var title = foo.GetTitle(expectedID);
// Assert
fooMock.Verify(x => x.GetTitle(It.Is<int>(c => expectedID == c)), Times.Once);
Assert.Equal($"Valid ID ({expectedResult})", title);
}
}

If you can separate your logic into a different method (what might be a better design too), than you can use Moq's CallBase property to make the test call the mocked method.
public abstract class FooBase
{
public virtual string GetTitle(int id) { return "Title From DB" /*Select From DB*/; }
}
public class Foo : FooBase
{
public virtual string GetValidatedTitle(int id)
{
if (id < 0)
return "Invalid id";
/*Doing somethings like other validations and etc*/
return $"Valid ID ({GetTitle(id)})";
}
}
public class FooTests
{
[Fact]
public void GetTitle() // Now Passes
{
// Arrange
var expectedID = 1;
var expectedResult = "Test";
var fooMock = new Mock<Foo>() { CallBase = true };
fooMock.Setup(x => x.GetTitle(It.IsAny<int>())).Returns(expectedResult);
var foo = fooMock.Object;
// Act
var title = foo.GetValidatedTitle(expectedID);
// Assert
fooMock.Verify(x => x.GetTitle(It.Is<int>(c => expectedID == c)), Times.Once);
Assert.Equal($"Valid ID ({expectedResult})", title);
}
}

Related

.net core xunit How verify if method was called from inherited class

I have a base class called BaseService, and i want to verify if method IsValid was called in my unit test.
public interface IBaseService
{
bool IsValid<Dto, DtoValidator>(Dto entityDto, DtoValidator validator) where DtoValidator : AbstractValidator<Dto>;
}
public class BaseService : IBaseService
{
protected readonly IMapper _mapper;
protected readonly INotificationService _notification;
public BaseService(
IMapper mapper,
INotificationService notification)
{
_mapper = mapper;
_notification = notification;
}
public virtual bool IsValid<Dto, DtoValidator>(Dto entityDto, DtoValidator validator) where DtoValidator : AbstractValidator<Dto>
{
var result = validator.Validate(entityDto);
foreach (var error in result.Errors)
{
_notification.Notify(error.ErrorMessage);
}
return result.IsValid;
}
}
Class that use BaseService , some parts of code was omited
public interface IAfiliadoService : IBaseService {}
public class AfiliadoService : BaseService, IAfiliadoService
{
public AfiliadoService(
IMapper mapper,
INotificationService notification) : base(mapper, notification)
{
_afiliadoRepository = afiliadoRepository;
_lojaRepository = lojaRepository;
}
public async Task<AfiliadoResponseDto> AddAsync(AddAfiliadoRequestDto request)
{
if (IsValid(request, new AddAfiliadoRequestDtoValidator()))
{
}
}
}
In my test project i created those classes
public class MockBaseService
{
public readonly Mock<IMapper> _mapper;
public readonly Mock<INotificationService> _notification;
public MockBaseService()
{
_mapper = new Mock<IMapper>();
_notification = new Mock<INotificationService>();
}
}
public class AfiliadoServiceTest : MockBaseService
{
private readonly IAfiliadoService _afiliadoService;
public AfiliadoServiceTest()
{
_afiliadoService = new AfiliadoService(
_mapper.Object,
_notification.Object);
}
[Fact]
public async Task AdicionarUsuarioComEmailQueJaExisteDeveNotificar()
{
var request = new AddAfiliadoRequestDto();
var result = await _afiliadoService.AddAsync(request);
Assert.Null(result);
_notification
.Verify(v => v.Notify(It.IsAny<string>()), Times.Once);
// Here i want verify if method IsValid was called Once, like the verification above
}
}
I tried some things but with no success.
Exemple with what i want.
var mock = new Mock<AfiliadoService>();
mock.Verify(v => v.IsValid(request, new AddAfiliadoRequestDtoValidator()), Times.Once);
var mock = new Mock<AfiliadoService>(_mapper.Object,
_notification.Object);
var result = await mock.Object.AddAsync(request);
mock.Verify(v => v.IsValid(request, new AddAfiliadoRequestDtoValidator()), Times.Once);
This last one i got the message
Message:
Moq.MockException :
Expected invocation on the mock once, but was 0 times: v => v.IsValid<AddAfiliadoRequestDto, AddAfiliadoRequestDtoValidator>(AddAfiliadoRequestDto, AddAfiliadoRequestDtoValidator)
Performed invocations:
Mock<AfiliadoService:1> (v):
BaseService.IsValid<AddAfiliadoRequestDto, AddAfiliadoRequestDtoValidator>(AddAfiliadoRequestDto, AddAfiliadoRequestDtoValidator)
What im doing wrong?
Im using .net core - 3.1
xunit - 2.4.1
Moq - 4.16.0

Unable to resolve service for type 'Api.Repositories.UnitOfWork' while attempting to activate 'Api.ServicesBusiness.EquipoServices'

I want to make a webapi and I'm trying to do it through the services way, I have a repository generic and another 2 repository and a unit of work, apparently everything goes fine, but when I run and test the webapi from postman I got that error:
InvalidOperationException: Unable to resolve service for type 'Api.Repository.Repositories.UnitOfWork' while attempting to activate 'Api.ServicesBusiness.Implementacion.EquipoServices'.
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateArgumentCallSites(Type serviceType, Type implementationType, CallSiteChain callSiteChain, ParameterInfo[] parameters, bool throwIfCallSiteNotFound)
Here is the my dbcontect:
public class AppDbContext : DbContext
{
public AppDbContext()
{
}
public AppDbContext(DbContextOptions<AppDbContext> option) :base(option)
{
}
public DbSet<Equipo> Equipos { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
optionsBuilder.UseSqlServer("Server=(localdb)\\Express;Database=SoftballLeague;Trusted_Connection=True");
}
}
}
Here is the interface of my generic repository:
public interface IGenericRepository<T> where T : class
{
Task<T> AddAsyn(T t);
Task<T> UpdateAsyn(T t, object key);
}
Here is the implementation of my generic repository:
public class GenericRepository<T> : IGenericRepository<T> where T : class
{
private readonly AppDbContext _context;
private readonly DbSet<T> _dbSet;
public GenericRepository(AppDbContext context)
{
_context = context;
_dbSet = _context.Set<T>();
}
public virtual async Task<T> AddAsyn(T t)
{
_dbSet.Add(t);
await _context.SaveChangesAsync();
return t;
}
public virtual async Task<T> UpdateAsyn(T t, object key)
{
if (t == null)
return null;
T exist = await _dbSet.FindAsync(key);
if (exist != null)
{
_context.Entry(exist).CurrentValues.SetValues(t);
await _context.SaveChangesAsync();
}
return exist;
}
}
Here is the interface of my equipo repository:
public interface IEquipoRepository:IGenericRepository<Team>
{
int GetAverageTeam(string name);
int GetTeamHit(string name);
}
Here is the implementation of my equipo repository:
public class EquipoRepository : GenericRepository<Team>, IEquipoRepository
{
private readonly AppDbContext dbContext;
public EquipoRepository(AppDbContext context) : base(context)
{
this.dbContext = context;
}
public int GetAverageTeam(string name)
{
int teamAverage = 0;
var resultAverage = this.dbContext.Equipos
//.SelectMany(bItem => bItem.)
.Where(equipo=>equipo.Nombre==name)
.SelectMany(equipo => equipo.jugadores)
.Average(jugador => jugador.Average);
if (resultAverage.HasValue)
teamAverage =Convert.ToInt32(Math.Round(resultAverage.Value));
return teamAverage;
}
public int GetTeamHit(string name)
{
int resultTotal = 0;
var result = this.dbContext.Equipos
//.SelectMany(bItem => bItem.)
.Where(equipo => equipo.Nombre == name)
.SelectMany(equipo => equipo.jugadores)
.Sum(jugador => jugador.Cant_Hits_Conectados);
if (result.HasValue)
resultTotal = result.Value;
return resultTotal;
}
}
Here is the interface of my unit of work:
public interface IUnitOfWork:IDisposable
{
Task Commit();
}
Here is the implementation of my unit of work:
public class UnitOfWork : IUnitOfWork
{
private readonly AppDbContext _DbContext;
private EquipoRepository equipoRepository ;
public UnitOfWork(AppDbContext dbContext)
{
this._DbContext = dbContext;
this.equipoRepository = new EquipoRepository(this._DbContext);
}
public EquipoRepository GetEquipoRepository{
get {
if(this.equipoRepository==null)
this.equipoRepository= new EquipoRepository(this._DbContext);
return this.equipoRepository;
}
}
public async Task Commit()
{
await this._DbContext.SaveChangesAsync();
}
public void Dispose()
{
this._DbContext.Dispose();
}
}
Here is the implementation of services interfaces IEquipoServices:
public interface IEquipoServices
{
ICollection<EstadisticaEquipoModel>AveragePorEquipo(string name);
int Total2bleConectados(string name);
}
Here is the implementation of services EquipoServices which is the one who throws the error:
public class EquipoServices : IEquipoServices
{
private readonly UnitOfWork unit;
public EquipoServices(UnitOfWork unitOfWorkFactory)
{
this.unit = unitOfWorkFactory;
}
public ICollection<EstadisticaEquipoModel> AveragePorEquipo(string name)
{
var equipoAverage= this.unit.GetEquipoRepository.GetAverageEquipo(name);
return equipoAverage;
}
public int AveragePorEquipo(string name)
{
var result = this.unit.GetEquipoRepository.GetEquipoTotal2bleConectados(name);
return result;
}
}
This is the controller, here I am just running the ListadoEquipos() method:
[Route("api/[controller]")]
public class EquipoController : ControllerBase
{
private readonly IEquipoServices equipoService;
private readonly IMapper _mapper;
public EquipoController(IEquipoServices eqService, IMapper mapper)
{
this.equipoService = eqService;
this._mapper = mapper;
}
[HttpGet("list")]
public IEnumerable<string> ListadoEquipos()
{
return new string[] { "value1", "value2" };
}
}
This is the configuration in the startup.cs file:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<AppDbContext>(options=>options.UseSqlServer(Configuration.GetConnectionString("ConnectionString")));
services.AddTransient<IUnitOfWork, UnitOfWork>();
services.AddScoped(typeof(IGenericRepository<>), typeof(GenericRepository<>));
services.AddSingleton<IEquipoServices, EquipoServices>();
//services.AddScoped<IJu, JugadorService>();
services.AddAutoMapper(typeof(Startup));
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
You registered IUnitOfWork, but you're injecting UnitOfWork. The service collection doesn't know how to inject UnitOfWork directly.
Long and short, inject IUnitOfWork instead:
private readonly IUnitOfWork unit;
public EquipoServices(IUnitOfWork unitOfWorkFactory)

Does the Repository connected to a Unit of Work need to be mocked for Unit Testing in ASP.NET Web API?

I have a Unit of Work pattern along with a Repo pattern to interact with the db layer (Entity Framework in this case) and then I have dependency injection going on in the controller's constructor. My question is, so I've mocked a IUnitOfWork which is what the controller interacts with, however, the Unit Of Work class actually accesses the repository so do I also have to mock a repository and if so, how would I implement this? I'm trying to complete a unit test of a basic Get controller method. I've read and watched several hours of video and articles and this is what I have so far:
class UrlControllerTests
{
[TestMethod]
public void ShouldReturnUrlList()
{
Mock<IUnitOfWork> fakeUnitOfWork = new Mock<IUnitOfWork>();
var urlController = new UrlController(fakeUnitOfWork.Object);
urlController.Get(5); //All this is just to see if we can get thru a test.
Assert.IsTrue(true);
}
IRepo
public interface IRepo<TEntity> where TEntity: class
{
TEntity Get(int id);
IEnumerable<TEntity> GetAll();
//Allows the running of lamba-style LINQ queries like the typical Entity Framework does:
IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate);
void Add(TEntity entity);
void AddRange(IEnumerable<TEntity> entities);
void Remove(TEntity entity);
void RemoveRange(IEnumerable<TEntity> entities);
}
IUnitOfWork:
public interface IUnitOfWork :IDisposable {
IRepo<Url> Urls { get; }
int Complete();
}
UnitOfWork:
public class UnitOfWork : IUnitOfWork
{
private readonly ApplicationDbContext _context;
public IRepo<Url> Urls { get; set; }
public UnitOfWork(ApplicationDbContext context)
{
_context = context;
Urls = new Repo<Url>(_context);
}
public int Complete()
{
return _context.SaveChanges();
}
public void Dispose()
{
_context.Dispose();
}
}
Repo:
public class Repo<TEntity> : IRepo<TEntity> where TEntity : class
{
protected readonly ApplicationDbContext _context;
public Repo(ApplicationDbContext context)
{
_context = context;
}
public TEntity Get(int id)
{
return _context.Set<TEntity>().Find(id);
}
//Repositories SHOULD NOT return IQueryable because otherwise other resources may
//Try to build queries
public IEnumerable<TEntity> GetAll()
{
return _context.Set<TEntity>().ToList();
}
public IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate)
{
return _context.Set<TEntity>().Where(predicate);
}
public void Add(TEntity entity)
{
_context.Set<TEntity>().Add(entity);
}
public void AddRange(IEnumerable<TEntity> entities)
{
_context.Set<TEntity>().AddRange(entities);
}
public void Remove(TEntity entity)
{
_context.Set<TEntity>().Remove(entity);
}
public void RemoveRange(IEnumerable<TEntity> entities)
{
_context.Set<TEntity>().RemoveRange(entities);
}
}
}
I am using moq.
EDIT: What I'm trying to test:
public IHttpActionResult Get(int id)
{
var url = _unitOfWork.Urls.Get(id);
if (url == null)
{
NotFound();
}
return Ok(url);
}
The Target Method under test is dependent on the IUnitOfWork and IRepo<Url>. When creating unit tests you would normally mock the dependencies of the system under test so that it can be tested in isolation without having dependencies calling actual implementations (Integration Tests).
[TestClass]
public class UrlControllerTests {
[TestMethod]
public void Get_With_Valid_Id_Should_Return_Url() {
//Arrange
var testId = 5;
var expected = new Url { Id = testId };
var mockRepo = new Mock<IRepo<Url>>();
mockRepo.Setup(m => m.Get(testId)).Returns(expected);
var mockUnitOfWork = new Mock<IUnitOfWork>();
mockUnitOfWork.Setup(m => m.Urls).Returns(mockRepo.Object);
var sut = new UrlController(mockUnitOfWork.Object);
//Act
var actionResult = sut.Get(testId) as OkNegotiatedContentResult<Url>;
//Assert
Assert.IsNotNull(actionResult);
Assert.AreEqual(expected, actionResult.Content);
}
}
Moq is flexible enough that you could also mock the entire dependency call so that you don't necessarily have to mock the repository if you have no need for more complicated setups.
The test would then be rewritten to
[TestClass]
public class UrlControllerTests {
[TestMethod]
public void Get_With_Valid_Id_Should_Return_Url() {
//Arrange
var testId = 5;
var expected = new Url { Id = testId };
var mockUnitOfWork = new Mock<IUnitOfWork>();
mockUnitOfWork.Setup(m => m.Urls.Get(testId)).Returns(expected);
var sut = new UrlController(mockUnitOfWork.Object);
//Act
var actionResult = sut.Get(testId) as OkNegotiatedContentResult<Url>;
//Assert
Assert.IsNotNull(actionResult);
Assert.AreEqual(expected, actionResult.Content);
}
}

Mock with Rhino mock -MVVM

I am using Rhino mock for mocking in my test methods. Could someone please see the TODO part in the test method and help me to mock it?
This is my service interface:
public interface ICustomersServiceAgent
{
void GetCustomers(EventHandler<GetCustomersCompletedEventArgs> callback);
void SaveCustomer(POC.Model.Customer cust, EventHandler<SaveCustomerCompletedEventArgs> callback);
}
This is my ViewModel
public class CustomerVM : ViewModelBase
{
private Model.Customer _curentCustomer;
private RelayCommand _saveCommand;
private ICustomersServiceAgent ServiceAgent { get; set; }
private bool isSaved;
private RelayCommand _calculateAgeCommand;
private Decimal age;
private DateTime dateOfBirth;
public CustomerVM(ICustomersServiceAgent serviceAgent)
{
if (serviceAgent == null)
{
ServiceAgent = ServiceManager.GetCustomerServiceManagement();
}
else
{
ServiceAgent =serviceAgent;
}
WireCommands();
}
// if curent object is null then it should be intialize
public Model.Customer CurentCustomer
{
get { return _curentCustomer ?? (_curentCustomer = new Model.Customer()); }
set
{
if (_curentCustomer != value)
{
_curentCustomer = value;
OnPropertyChanged("CurentCustomer");
}
}
}
public RelayCommand CalculateAgeCommand
{
get;
private set;
}
private void WireCommands()
{
SaveCustomerCommand = new RelayCommand(SaveCustomer);
SaveCustomerCommand.IsEnabled = true;
CalculateAgeCommand = new RelayCommand(CalculateAge);
}
private void SaveCustomer()
{
var cus = CurentCustomer;
ServiceAgent.SaveCustomer(cus, (s, e) =>
{
IsSaved = e.Result;
});
}
private void CalculateAge()
{
Age = DateTime.Now.Year - DateOfBirth.Year;
}
public RelayCommand SaveCustomerCommand
{
get;
private set;
}
public bool IsSaved
{
get { return isSaved; }
set
{
isSaved = value;
OnPropertyChanged("IsSaved");
}
}
public decimal Age
{
get { return age; }
set {
age = value;
OnPropertyChanged("Age");
}
}
public DateTime DateOfBirth
{
get { return dateOfBirth; }
set {
dateOfBirth = value;
OnPropertyChanged("DateOfBirth");
}
}
}
I want to test the SaveCustomerCommand in ViewModel above.
So In the my test method, I want to mock the void SaveCustomer(POC.Model.Customer cust, EventHandler<SaveCustomerCompletedEventArgs> callback) method in the ICustomersServiceAgent interface.
This is my test method, see the ToDo part
[TestMethod]
public void SaveCustomerCommandTest()
{
var customerServiceMock = MockRepository.GenerateMock<ICustomersServiceAgent>();
var customerVM = new POC.SilverlightClient.ViewModel.CustomerVM(customerServiceMock);
// TO do : Code to mock SaveCustomer method ///////////////////////////////////
var saveCustomerCommand = customerVM.SaveCustomerCommand;
saveCustomerCommand.Execute(null);
Assert.IsTrue(customerVM.IsSaved);
}
Could someone please explain how I can do this?
I don't see why you need to mock SaveCustomer. All the private SaveCustomer method does is invoke the ServiceAgent service which you already are mocking. I assume the RelayCommand class invokes the delegate you're sending in the constructor parameter which is the call to SaveCustomer. Have you tried running the unit test in your question as-is?
Try following:
customerServiceMock.Stub(sa => sa.SaveCustomer(Arg<POC.Model.Customer>.Is.Anything, Arg<EventHandler<SaveCustomerCompletedEventArgs>>.Is.Anything)).WhenCalled(invocation =>
{
((EventHandler<SaveCustomerCompletedEventArgs>)invocation.Arguments[1])(
customerServiceMock,
new SaveCustomerCompletedEventArgs { Result = true });
});

Mocking, Unit Testing (NUnit) setup problem with HttpHandler

This post relates to two other posts, here and here.
I'm new to Unit Testing & Mocking. I have a test fixture that is trying to mock a HttpContext object including the response and request. I think the test code is not setup properly, as after calling the handler I get an error immediately. There error I am getting is:
UnitTests.UADHandlerFixture.Request_Is_Object:
System.NullReferenceException : Object reference not set to an instance of an object.
at Abstract.BaseHttpHandler.get_Request() in BaseHttpHandler.cs:line 21
at Abstract.BaseHttpHandler.get_IsRequestFromUAD() in BaseHttpHandler.cs:line 23
at Handlers.UADTimeHttpHandler.ProcessRequest(HttpContextBase context) in UADTimeHttpHandler.cs:line 19
at UnitTests.UADHandlerFixture.Request_Is_Object() in UADHttpHanderTests.cs:line 47
The test code is this:
[TestFixture]
public class UADHandlerFixture
{
private Mock<HttpContextBase> _mockHttpContext;
private Mock<HttpRequestBase> _mockHttpRequest;
private Mock<HttpResponseBase> _mockHttpResponse;
private UADTimeHttpHandler _handler;
private WindsorContainer _container;
[SetUp]
public void Init()
{
_mockHttpRequest = new Mock<HttpRequestBase>();
_mockHttpResponse = new Mock<HttpResponseBase>();
_mockHttpContext = new Mock<HttpContextBase>();
_container = new WindsorContainer();
_container.AddComponent<ILogger, FakeLogger>();
_container.AddComponent<IDataRepository, FakeDataRepository>();
_mockHttpContext.SetupGet(x => x.Application[0]).Returns(_container);
_mockHttpContext.SetupGet(x => x.Request).Returns(_mockHttpRequest.Object);
_mockHttpContext.SetupGet(x => x.Response).Returns(_mockHttpResponse.Object);
_handler = new UADTimeHttpHandler();
}
[Test]
public void Request_Is_Object()
{
_handler.ProcessRequest(_mockHttpContext.Object);
}
}
Handler:
public class UADTimeHttpHandler : BaseHttpHandler
{
public override void ProcessRequest(HttpContextBase context)
{
if (IsRequestFromUAD)
{
Logger.Log("Log stuff");
DataRepository.Write("DB stuff");
ReturnResponse(HttpStatusCode.OK, DateTime.Now.ToString());
}
else
ReturnResponse(HttpStatusCode.BadRequest);
}
}
BaseHandler:
public abstract class BaseHttpHandler : IHttpHandler
{
private HttpContext _httpContext;
private ILogger _logger;
private IDataRepository _dataRepository;
protected ILogger Logger { get { return _logger; } }
protected IDataRepository DataRepository { get { return _dataRepository; } }
protected HttpContext Context { get { return _httpContext; } }
protected HttpRequest Request { get { return _httpContext.Request; } }
protected HttpResponse Response { get { return _httpContext.Response; } }
protected bool IsRequestFromUAD { get { return Request.UserAgent == null ? false : Request.UserAgent.Equals("UAD"); } }
public virtual bool IsReusable { get { return false; } }
public void ProcessRequest(HttpContext context)
{
WindsorContainer container = (WindsorContainer)context.Application[0];
_logger = container.Resolve<ILogger>();
_dataRepository = container.Resolve<IDataRepository>();
_httpContext = context;
ProcessRequest(new HttpContextWrapper(context));
}
protected virtual void ReturnResponse(HttpStatusCode httpStatus)
{
Response.StatusCode = (int)httpStatus;
}
protected virtual void ReturnResponse(HttpStatusCode httpStatus, string response)
{
Response.StatusCode = (int)httpStatus;
Response.Write(response);
}
protected virtual string GetInputStream()
{
using (var reader = new StreamReader(Request.InputStream))
{
return reader.ReadToEnd();
}
}
public abstract void ProcessRequest(HttpContextBase context);
}