New in using FakeItEasy. I'm getting error at
A.CallTo(() => Lister.GetResult(A<int>._, A<int>._)).MustHaveHappened();
so I guess this
A.CallTo(() => Lister
.GetResult(A<int>._, A<int>._))
.Returns(new ResponseList(1, new List<RecordsValues>())) ;
is not being triggered. When I removed the .MustHaveHappened assertion, the test proceeds, also getting 200 statuscode (a controller is in test). It passes on the 2nd code snippet above but throws no error.
Any advice is appreciated.
Test
public class GetByListTests
{
[Fact]
public void GetByList_GetFieldsByRange_Test()
{
ILister Lister = A.Fake<ILister>();
IDbConnectionFactory dbConnectionFactory = A.Fake<IDbConnectionFactory>();
GetByList GetByList = new(dbConnectionFactory);
A.CallTo(() => Lister
.GetResult(A<int>._, A<int>._))
.Returns(new ResponseList(1, new List<RecordsValues>()));
//result contains empty and 0 values, with 200 statuscode
//result it does not contain the expected return declared on the above callTo return
var result = (OkObjectResult)GetByList.GetFieldsByRange();
//if I remove this, the test passes but with incorrect result value, so I assume it really is not being called as when I add the line below, it errs out
A.CallTo(() => Lister.GetResult(A<int>._, A<int>._)).MustHaveHappened();
Assert.NotNull(result);
Assert.Equal(200, result.StatusCode);
}
}
Endpoint
private readonly ILister Lister;
public GetByList(IDbConnectionFactory dbConnectionFactory)
{
DataService securityProjectDataService = new(dbConnectionFactory);
Lister = new SecurityProjectLister(DataService);
}
[HttpGet]
public IActionResult GetFieldsByRange([FromQuery][Range(0, int.MaxValue)] int skip = 0, [FromQuery][Range(0, 1000)] int top = 1000)
{
ResponseList response = securityProjectLister.GetResult(skip, top);
return Ok(response);
}
If I lack something, please point out. I'm happy to take any learnings. Thanks and cheers!
I think the main issue is that you are never actually using the ILister
fake.
The fake you have created resides inside your test method,
ILister Lister = A.Fake<ILister>();
whereas you create a separate ILister
object in your endpoint class:
Lister = new SecurityProjectLister(DataService);
In order to actually benefit from your ILister
fake, you need dependency injection of an ILister
object in your enpoint class.
As it currently stands, I find your endpoint class snippet a little difficult to understand. I believe some names have been mixed up, so that the current implementation:
private readonly ILister Lister;
public GetByList(IDbConnectionFactory dbConnectionFactory)
{
DataService securityProjectDataService = new(dbConnectionFactory);
Lister = new SecurityProjectLister(DataService);
}
[HttpGet]
public IActionResult GetFieldsByRange(...)
{
ResponseList response = securityProjectLister.GetResult(skip, top);
return Ok(response);
}
should in fact be this:
private readonly ILister securityProjectLister; // EDITED
public GetByList(IDbConnectionFactory dbConnectionFactory)
{
DataService securityProjectDataService = new(dbConnectionFactory);
securityProjectLister = new SecurityProjectLister(securityProjectDataService); // EDITED
}
[HttpGet]
public IActionResult GetFieldsByRange(...)
{
// Now, your ILister object is used here:
ResponseList response = securityProjectLister.GetResult(skip, top);
return Ok(response);
}
If this is the case, I actually believe you will need to extract the creation of both the DataService
object and the ILister
object to outside of your endpoint class, and provide your endpoint class constructor with an ILister
object.
I believe a possible implementation could be similar to the following:
Endpoint class snippet:
private readonly ILister securityProjectLister;
public GetByList(ILister lister)
{
securityProjectLister = lister;
}
[HttpGet]
public IActionResult GetFieldsByRange(...)
{
// Remains unchanged
}
Test method:
public void GetByList_GetFieldsByRange_Test()
{
IDbConnectionFactory dbConnectionFactory = A.Fake<IDbConnectionFactory>();
DataService securityProjectDataService = new(dbConnectionFactory);
ILister Lister = new SecurityProjectLister(securityProjectDataService);
GetByList GetByList = new(Lister);
// Unchanged:
A.CallTo(() => Lister
.GetResult(A<int>._, A<int>._))
.Returns(new ResponseList(1, new List<RecordsValues>()));
// The remaining code remains unchanged
}
Now, the GetByList
object is using the very ILister
object on which you have configured A.CallTo(...).Returns(...);
in your test method.