Mocking UnitOfWork/GenericRepository with Moq - c#

I'm running into an issue where Moq doesn't return what I excpect using following code:
[TestMethod]
public void GetResultReturnsAResult()
{
var mockUnitOfWork = Arrange();
// Arrange
var controller = new ResultsController(mockUnitOfWork.Object);
controller.Request = new HttpRequestMessage();
controller.Configuration = new HttpConfiguration();
// Act
var response = controller.GetResult(2);
// Assert
Assert.IsTrue(response is OkNegotiatedContentResult<Result>);
var contentResult = response as OkNegotiatedContentResult<Result>;
Assert.IsNotNull(contentResult);
Assert.IsNotNull(contentResult.Content);
Assert.IsTrue(contentResult.Content.ID == 2);
}
[TestMethod]
public void GetResultReturnsNotFound()
{
var mockUnitOfWork = Arrange();
// Arrange
var controller = new ResultsController(mockUnitOfWork.Object);
controller.Request = new HttpRequestMessage();
controller.Configuration = new HttpConfiguration();
// Act
var response = controller.GetResult(100);
// Assert
Assert.IsTrue(response is NotFoundResult);
var contentResult = response as NotFoundResult;
Assert.IsNotNull(contentResult);
}
private Mock<IUnitOfWork> Arrange()
{
var results = new List<Result>()
{
new Result()
{
ID = 1,
Name = "Result 1",
Modified = new DateTime(2017, 1, 1),
Created = new DateTime(2017, 1, 1),
CreatedBy = "Tester 1",
ModifiedBy = "Tester 2"
},
new Result()
{
ID = 2,
Name = "Result 2",
Modified = new DateTime(2017, 1, 2),
Created = new DateTime(2017, 1, 2),
CreatedBy = "Tester 1",
ModifiedBy = "Tester 2"
},
};
var mockUnitOfWork = new Mock<IUnitOfWork>();
var mockResultRepository = new Mock<IGenericRepository<Result>>();
mockResultRepository.Setup(x => x.Get(null, null, ""))
.Returns(results);
mockResultRepository.Setup(x => x.GetById(It.IsAny<int>()))
.Returns((int id) => GetById(results, id));
mockUnitOfWork.Setup(x => x.ResultRepository)
.Returns(mockResultRepository.Object);
return mockUnitOfWork;
}
private Result GetById(List<Result> results, int id)
{
return results.FirstOrDefault(r => r.ID == id);
}
In this case my TestMethods testing GetById both throw an exception with message: Object of type 'System.Object[]' cannot be converted to type 'System.Int32'.
When I change the mocking code to this:
mockResultRepository.Setup(x => x.Get(null, null, ""))
.Returns(results);
mockUnitOfWork.Setup(x => x.ResultRepository)
.Returns(mockResultRepository.Object);
mockUnitOfWork.Setup(x => x.ResultRepository.GetById(It.IsAny<int>()))
.Returns((int id) => GetById(results, id));
The GetById tests don't throw an exception but GetResultReturnsAResult doesn't return a result so it always fails.
Can anyone shed a light on this behaviour?

As suggested by Eugene Podskal in the comments, I was creating an MCVE (download here) and ran into the solution. He was in fact right that the solution was to be found in code that was not shared first.
The code that returned the
Object of type 'System.Object[]' cannot be converted to type 'System.Int32'
exception was correct in throwing this exception since
GetById
takes a
params object[]
as first parameter.

Related

Cannot get unit test to pass (httpRequest mock )

I wrote a unit test thats failing:
[Test]
public async Task GetLogsPaged_Account_ExpectsSuccess()
{
//Arrange
var request = new Mock<HttpRequest>();
request.Setup(x => x.Scheme).Returns("https");
request.Setup(x => x.Host).Returns(HostString.FromUriComponent("https://localhost:5001"));
request.Setup(x => x.PathBase).Returns(PathString.FromUriComponent("/v1/customersupport-manager/logs/account/D4C88E3C-2848-400F-AB66-0DC3FAFFD24A?PageNumber=1&PageSize=5&DateFrom=2021-09-30%2012%3A30%3A13.413&DateTo=2021-09-30%2012%3A33%3A05.317"));
List<LogEntry> logEntries = new List<LogEntry>() { new LogEntry { Id = 1 }, new LogEntry { Id = 2 } };
PaginationFilter paginationFilter = new PaginationFilter { };
LogEntryListFilter logEntryListFilter = new LogEntryListFilter { };
var accountId = Guid.NewGuid();
LogEntryPageResult logs = new LogEntryPageResult() { PagedRecords = logEntries };
A.CallTo(() => logRepo.GetLogs(A<Guid>._, A<PaginationFilter>._, A<LogEntryListFilter>._)).Returns(logs);
//Act
var result = await svc.GetLogs(accountId, request.Object, paginationFilter, logEntryListFilter);
//Assert
result.ApplicationEvents[0].Code.Should().Be(ApplicationResponseCodes.System.OperationSucceed);
}
When I debug the test I get a exception that says - {"Object reference not set to an instance of an object."} System.Exception {System.NullReferenceException}.
Which can only be var request because it's mocked. I'm not sure why I'm getting this exception when I've seen HttpRequest being mocked in other tests. Any assistance is appreciated.
Edit: I'm including the the line that fails in my code
var uri = new Uri(request.GetDisplayUrl()); <- System.NullReference
But I have the url specified in my tests :
request.Setup(x => x.Scheme).Returns("https");
request.Setup(x => x.Host).Returns(HostString.FromUriComponent("https://localhost:5001"));
request.Setup(x => x.PathBase).Returns(PathString.FromUriComponent("/v1/customersupport-manager/logs/account/D4C88E3C-2848-400F-AB66-0DC3FAFFD24A?PageNumber=1&PageSize=5"));

FakeitEasy - EntityFramework

I am writing an unit test to test my EF project . while doing the test I am getting an error while configuraing the fake for the DBSet.
My Call stack is
System.NotImplementedException
The member 'IQueryable.ElementType' has not been implemented on type
'DbSet`1Proxy_10' which inherits from 'DbSet`1'. Test doubles for 'DbSet`1'
must provide implementations of methods and properties that are used.
at
system.Data.Entity.Infrastructure.DbQuery`1.GetInternalQueryWithCheck(String
memberName)
at
My Unit Test Code is - I had added a mapping data
var socMappingList = new List<DFC_SocMappings>()
{
new DFC_SocMappings()
{
JobProfile = "Police Officer",
ONetCode = "111-00.01",
QualityRating = 4,
SocCode = "1120"
},
new DFC_SocMappings()
{
JobProfile = "Police Officer",
ONetCode = "111-00.02",
QualityRating = 4,
SocCode = "1121"
},
};
//Arrange
var applicationLogger = A.Fake<IApplicationLogger>();
var fakeIQueryable = new List<DFC_SocMappings>().AsQueryable();
var context = A.Fake<IObjectContextFactory<OnetRepositoryDbContext>>();
// var fakeDbSet = A.Fake<DbSet<DFC_SocMappings>>();
IMapper iMapper = new AutoMapper.Mapper(new MapperConfiguration(cfg => cfg.AddProfile(new SkillsFrameworkMapper())));
var fakeDbSet = A.Fake<DbSet<DFC_SocMappings>>((d => d.Implements(typeof(IQueryable<DFC_SocMappings>)).Implements(typeof(IDbAsyncEnumerable<DFC_SocMappings>)))).SetupData(socMappingList);
A.CallTo(() => context.GetContext().DFC_SocMappings).Returns(fakeDbSet);
var ct = A.Fake<OnetRepository>(op => op.WithArgumentsForConstructor(new object[] { context, iMapper, applicationLogger }));
//Act
A.CallTo(() => ((IQueryable<DFC_SocMappings>)fakeDbSet).Provider).Returns(fakeIQueryable.Provider);
A.CallTo(() => ((IQueryable<DFC_SocMappings>)fakeDbSet).Expression).Returns(fakeIQueryable.Expression);
A.CallTo(() => ((IQueryable<DFC_SocMappings>)fakeDbSet).ElementType).Returns(fakeIQueryable.ElementType);
A.CallTo(() => ((IQueryable<DFC_SocMappings>)fakeDbSet).GetEnumerator()).Returns(fakeIQueryable.GetEnumerator());
//Assert
var onetRespository = new OnetRepository(context, iMapper, applicationLogger);
var response = await onetRespository.GetAllSocMappingsAsync<DfcOnetSocMappings>();
var res = response; // failing while reading the data
A.CallTo(() => context.GetContext().Set<DFC_SocMappings>()).MustHaveHappened();
response.Should().NotBeNull();
response.Should().BeSameAs(socMappings);
onetRespository.Dispose();
Can someone tell what mistake I am doing.

Unable mock an enumerable result from a task

I want to mock the UniteofWork.FileApproveOverrideRepo.GetAllOverrideApprovals method
Everything working based on the code below just mylist is empty.
public async Task<List<FileApprovalOverrideResponse>> GetAllOverrideApprovals(int cpId)
{
var overrideApprovals = await UnitOfWork.FileApprovalOverrideRepository.Get(t => t.CPId == cpId, null, t => t.ActionedByUser.Company);
var mylist = overrideApprovals.ToList();
return MapperInstance.Map<List<FileApprovalOverrideResponse>>(mylist);
}
And here is how I mock my method :
var mockedUnitOfWork = new Mock<IUnitOfWork>();
var mockedGenericRepoCPApproval = new Mock<IGenericAsyncRepository<FileApprovalOverride>>();
var listOfFileApprovalOverrride = new FileApprovalOverride[] {
new FileApprovalOverride()
{
FileApprovalOverrideId = 2,
FileId = 2,
CPId = 2,
ApprovalStatus = 3,
IntendedApproverType = (byte)approvType,
IsValid = true,
Reason = ""
},
new FileApprovalOverride()
{
FileApprovalOverrideId = 2,
FileId = 2,
CPId = 2,
ApprovalStatus = 3,
IntendedApproverType = (byte)approvType,
IsValid = true,
Reason = "",
}
};
var myenumerable = listOfFileApprovalOverrride;
mockedGenericRepoCPApproval.Setup(_ => _.Get(t => t.CPId == 1, null, t => t.ActionedByUser.Company)).ReturnsAsync(myenumerable);
mockedUnitOfWork.Setup(_ => _.FileApprovalOverrideRepository).Returns(mockedGenericRepoCPApproval.Object);
var cpApprovalService = new CpApprovalService(mockCPApprovalRepository.Object, new Mock<ICPRepository>().Object, new Mock<ICPService>().Object, new Mock<ICompanyRepository>().Object, new Mock<ICPLinkedCompanyService>().Object, new Mock<ICPExportService>().Object, new Mock<IEmailService>().Object, new Mock<ICPContactService>().Object, new Mock<ISystemUserRespository>().Object, new Mock<IUserManagementService>().Object, new Mock<IAuditLogService>().Object, new Mock<ISignCharterParty>().Object, new Mock<IEmailQueuer>().Object);
cpApprovalService.UnitOfWork = mockedUnitOfWork.Object;
cpApprovalService.MapperInstance = mapperInstanse;
return cpApprovalService;
I put a break point where I am creating the mock even there the myenumerable is correct and it has two members but when I run the test then the mylist is empty.

Unit test a SelectList object returned as JsonResult

I'm struggling to test the method below:
public JsonResult GetJsonObjectsFromOffices(int siteId)
{
IEnumerable<Office> officeList;
officeList = repository.Offices
.Where(o => o.SiteID == siteId)
.OrderBy(o => o.Name);
return Json(new SelectList(officeList, "OfficeID", "Name"));
}
Using Moq and xUnit, I have the following test
//Arrange
Mock<IFormRepository> mockRepo = new Mock<IFormRepository>();
var mockUserMgr = GetMockUserManager();
var userValid = new CustomUserValidator();
var passwordValid = new CustomPasswordValidator();
var passwordHash = new PasswordHasher<AppUser>();
mockRepo.Setup(m => m.Offices).Returns(new Office[]
{
new Office {OfficeID = 2, SiteID = 2, Name = "Bravo"},
new Office {OfficeID = 1, SiteID = 1, Name = "Alpha"},
new Office {OfficeID = 3, SiteID = 1, Name = "Charlie"}
}.AsQueryable<Office>());
AdminController controller = new AdminController(mockUserMgr.Object, userValid, passwordValid, passwordHash, mockRepo.Object);
//Act
var jsonObj = controller.GetJsonObjectsFromOffices(1);
//'Unexpected character encountered while parsing value: M. Path '', line 0, position 0.' error on line below
//var selectList = JsonConvert.DeserializeObject(jsonObj.Value.ToString());
The goal on the Assert portion of the test would be to verify that the correct number of list items was returned (i.e. two items corresponding to SiteID = 1).
The jsonObj is a JsonResult type, with a value of {Microsoft.Mvc.Rendering.SelectList}. Within the SelectList, the correct Items are produced, but I don't know how to access them to count
The value stored in the result would be of the type passed to it.
Cast the expected value to the expected type and do the assertions on that if it cast successfully
//...code removed for brevity
//Act
var jsonResult = controller.GetJsonObjectsFromOffices(1);
//Assert
var selectList = jsonResult.Value as SelectList;
Assert.NotNull(selectList); //<-- cast was successful
var expected = 2;
var actual = selectList.Count();
Assert.Equal(expected, actual);

moq does not return what I defined in mock.Setup

I am mocking a function in c# using Moq.
public void Mapper_GetProductMappingTest()
{
//Arrange:
Mapping mapping= new Mapping()
{
code = "AB"
};
Mapper mapper = new Mapper(new MongoStore());
CaseProduct caseProduct = new CaseProduct()
{
ProductID = "ABC",
};
Mock<Mapper> mock = new Mock<Mapper>(new MongoStore());
mock.Setup(x => x.GetMapping(caseProduct)).Returns(mapping);
// why does it return the caseproduct not the mapping?!
var mapped = mock.Object.GetMapping(caseProduct);
Assert.IsTrue(mapped.code == "AB");
This Assert.IsTrue is failed and the mock.Object.GetMapping(caseProduct) returns ABC insteadof AB.
Can somebody help me with that?

Categories