public class UserService
{
IUserRepo userRepo;
UserService(IUserRepo repo)
{
userRepo = repo;
}
void AddUser(JsonData data)
{
User user = new User()
{
Name = data.name,
Number = data.Number
};
userRepo.Insert(user);
int id = user.id;
}
}
id is 0 when a unit test case is debugged, but when it is a proper call it returns proper primary key i.e. 1, 2, 3, etc.
Mock
class TestCases
{
Mock<IUserRepo> mockUserRepo = new Mock<IUserRepo>();
[Test]
public void test1()
{
//Arrange
JsonData obj = new JsonData()
{
Name = "Jane",
Number = "0563722992"
}
User dumpUser= new User()
{
Name = "Def",
Number = "8111"
};
mockUserRepo
.Setup(x => x.Insert(It.IsAny<User>()))
.Callback(() => dumpUser.Id = 1);
//Act
UserService u = new UserService(mockUserRepo.Object);
u.AddUser(obj);
//Assert
}
}
While debugging the unit test it seems that callback is unable to change the id to 1 when it passes through the method Insert().
Can anybody help how to tackle with this issue?
There is no need for
User dumpUser= new User()
{
Name = "Def",
Number = "8111"
};
As the method under test creates/initializes it's own instance within.
Capture the passed argument in the call back and update the desired member there
//...
userRepo
.Setup(x => x.Insert(It.IsAny<User>()))
.Callback((User arg) => arg.Id = 1);
//...
Related
I am trying to test a method that is using two different interfaces.
Using Moq I configure the interfaces methods and set a return object, but just the first method executed returns value, the second returns null, no matter what I set as Returns.
This is an example :
Interface 1
public interface IUserRepository
{
User GetUserById(int id);
}
Interface 2
public interface ICallApiService
{
ApiResponseDto ValidateUser();
}
Class I want to test
public class UserServices : IUserServices
{
private IUserRepository _userRepository;
private ICallApiService _callApiService;
public UserServices(IUserRepository userRepository, ICallApiService callApiService)
{
_userRepository = userRepository;
_callApiService = callApiService;
}
public User GetUserById(int id)
{
//result always have a value set to result
var result = _callApiService.ValidateUser();
//result2 is always null
var result2 = _userRepository.GetUserById(result.UserId);
return result2;
}
}
The Test Method
[TestMethod]
public void TestMethod1()
{
moqUserRepository = new Moq.Mock<IUserRepository>();
moqUserRepository.Setup(s => s.GetUserById(1)).Returns(new User() { Id = 100, Birth = DateTime.Now, Email = "g#test.com", Name="g" });
moqCallApiService = new Moq.Mock<ICallApiService>();
moqCallApiService.Setup(s => s.ValidateUser()).Returns(new ApiResponseDto() { Active = true, Messages = "None", UserId = 100 });
var userService = new UserServices(moqUserRepository.Object, moqCallApiService.Object);
var resultInstance = userService.GetUserById(1);
var moqUserService = new Moq.Mock<UserServices>(moqUserRepository.Object, moqCallApiService.Object).Object;
var resultMock = moqUserService.GetUserById(1);
}
In both cases using instance and mock i get the same error (return null).
Am I missing something to Moq ?
You're instructing the repository mock to return an object when the input parameter id has the value 1. But the service code calls the repository with the value of result.UserId which is set to be 100 by the other mock setup call.
Change the first setup call to
moqUserRepository.Setup(s => s.GetUserById(100)).Returns(new User() { Id = 100, Birth = DateTime.Now, Email = "g#test.com", Name="g" });
Or use It.IsAny, since you don't really care about the value when you only have a single mocked call to the method:
moqUserRepository.Setup(s => s.GetUserById(It.IsAny<int>())).Returns(new User() { Id = 100, Birth = DateTime.Now, Email = "g#test.com", Name="g" });
I`m trying to use Moq to test EntityFramework code, and somehow it returns zero results after setup.
I tried to make a parameter-less constructor on workersController - same zero items returned
public class WorkerDbTest
{
private readonly Mock<IWorkerReprisatory> _repo;
private readonly WorkersController _controller;
private readonly List<Worker> workers;
public WorkerDbTest()
{
_logger = new Mock<ILogger<WorkersController>>();
workers = new List<Worker>
{
new Worker() {
Id = 0,
FirstName = "John",
MiddleName = "Abraham",
LastName = "Doe",
Workplace = "Bomj",
BirthDate = new DateTime(1700,10,10),
Employed = new DateTime(1800,10,10)},
new Worker() {
Id = 1,
FirstName = "Alaster",
MiddleName = "Crowly",
LastName = "Johns",
Workplace = "VipBomj",
BirthDate = new DateTime(1800,12,12),
Employed = new DateTime(1900,12,12)},
new Worker() {
Id = 2,
FirstName = "Jane",
MiddleName = "Susan",
LastName = "Black",
Workplace = "FemenistBobj",
BirthDate = new DateTime(2000,11,11),
Employed = new DateTime(2010,11,11)}
};
IQueryable<Worker> workersq = workers.AsQueryable();
_repo = new Mock<IWorkerReprisatory>();
_repo.Setup(x => x.GetAll(new WorkerQueryParameters())).Returns(workersq);
}
[Fact]
public void GetOkResult()
{
var tst = _repo.Object.GetAll(new WorkerQueryParameters());
}
}
//Controller class GetAllWorkers
public IActionResult GetAllWorkers(WorkerQueryParameters workerQueryParameters)
{
//_logger.LogInformation("GetAllCustomersStarted");
var allWorkers = _workerRepository.GetAll(workerQueryParameters).ToList();
var allWorkersDTO = allWorkers.Select(x => Mapper.Map<WorkerDTO>(x));
if(Response != null)
{
Response.Headers.Add("X-Pagination",
JsonConvert.SerializeObject(new { totalCount = _workerRepository.Count() }));
}
return Ok(allWorkersDTO);
}
At the current time allWorkers object results 0 entries after being called.
So I wanted to test out if I have any result from Mock object which then got var tst and there are still no entries.
Suppose that GetAll() Should return me those three guys I added there as iQueryables
Your setup method is matching on the an actual object refrence of WorkerQueryParameters, you'll need to use the same object refrence or, you'll need to match a given value with It.Is<WorkerQueryParameters>(x => x.Value == true) or just match any It.Any<WorkerQueryParameters>(), for example:
_repo.Setup(x => x.GetAll(It.Any<WorkerQueryParameters>())).Returns(workersq);
It might also be worth setting your mock to be strick so that it throws instead of just returning null or default.
_repo = new Mock<IWorkerReprisatory>(MockBehavior.Strict);
Somewhy adding a param at startup and using it instead of New WorkerQueryParams() did the trick. I still have no idea why, but it works perfectly fine, and returns 3 entries.
Thanks to everyone envolved and #Nikosi for his idea)
_params= new WorkerQueryParameters()
_repo.Setup(x => x.GetAll(_params)).Returns(workersq);
IQueryable<Worker> tst = _repo.Object.GetAll(_params);
var OkResponse = _controller.GetAllWorkers(_params);
I am creating some unit tests for a controller I have however I ran into a problem.
Basically I have the following:-
The Controller Method :-
[ResponseType(typeof(Attrib))]
public IHttpActionResult GetAttrib(int id)
{
var attrib = _attribsRepository.GetAttrib(id);
if (attrib == null)
{
return NotFound();
}
return Ok(attrib);
}
Its a simple Web API 2.0 method.
Then I have the Repository :-
public Attrib GetAttrib(int id)
{
return DbSet.FirstOrDefault(x=>x.Id == id);
}
And finally the Test Method:-
public class AttribsControllerTests
{
public Mock<IAttribsRepository> _attribsRepositoryMock;
public List<Attrib> AttribList;
public AttribsController AttribsController;
[SetUp]
public void Init()
{
_attribsRepositoryMock = new Mock<IAttribsRepository>();
AttribList = new List<Attrib>
{
new Attrib()
{
Id = 1,
AttributeId = "Cro",
AttributeName = "Crossing",
AttributeType = "Tech",
AttributeValue = 1
},
new Attrib()
{
Id = 2,
AttributeId = "Dri",
AttributeName = "Dribbling",
AttributeType = "Tech",
AttributeValue = 2
},
new Attrib()
{
Id = 3,
AttributeId = "Fin",
AttributeName = "Finishing",
AttributeType = "Tech",
AttributeValue = 3
}
};
}
[Test]
public void Get_Check_That_Id1_Returns_Crossing()
{
//Arrange
_attribsRepositoryMock.Setup(t => t.GetStaticAttribs()).Returns(AttribList.AsQueryable());
//Act
var attribsController = new AttribsController(_attribsRepositoryMock.Object);
var result = attribsController.GetAttrib(1) as OkNegotiatedContentResult<Attrib>;
//Assert
Assert.IsNotNull(result);
Assert.AreEqual(AttribList[0].AttributeName, "Cor");
}
}
For some reason, the result is always null, so its not hitting the controller correctly.
Any ideas why this could happen? When debugging, the correct Mock Repository is hitting the controller, and it should have the 3 entries in it.
Any help will be very much appreciated.
You setup GetStaticAttribs but it is used nowhere in the example you showed. You were suppose to setup IAttribsRepository.GetAttrib
Based on your example
[Test]
public void Get_Check_That_Id1_Returns_Crossing() {
//Arrange
var id = 1;
_attribsRepositoryMock.Setup(t => t.GetAttrib(id)).Returns(AttribList[0]);
var attribsController = new AttribsController(_attribsRepositoryMock.Object);
//Act
var result = attribsController.GetAttrib(id) as OkNegotiatedContentResult<Attrib>;
//Assert
Assert.IsNotNull(result);
Assert.IsNotNull(result.Content);
Assert.AreEqual(result.Content.AttributeName, "Crossing");
}
I have some problem with unit test of my repository, especially with method FindBy()
public IQueryable<T> FindBy(Expression<Func<T, bool>> predicate)
{
return Entities.Where(predicate);
}
Entities is IDbSet<T> Entities = _context.Set<T>();
I'm trying to test the method in controller, but I always get NULL in houses.
Could you give any advice what should I do with it?
public override HttpResponseMessage Get()
{
var houses = Repository.FindBy(y => y.Year == DateTime.Now.Year);
if (houses != null && houses.Any())
{
return Request.CreateResponse(HttpStatusCode.OK, houses);
}
const string message = "House: No content";
return ErrorMsg(HttpStatusCode.NotFound, message);
}
Here is my test method
[TestMethod]
public void GetAll()
{ //Arrange
var houses = new List<House>
{
new House {ID = 1, BuildNr = "01", HouseNr = "001" },
new House {ID = 2, BuildNr = "02", HouseNr = "002" },
new House {ID = 3, BuildNr = "03", HouseNr = "003" },
new House {ID = 4, BuildNr = "04", HouseNr = "004" },
new House {ID = 5, BuildNr = "05", HouseNr = "005" }
};
var mock = new Mock<IRepository<T>>();
mock.Setup(m => m.FindBy(f => f.Year == It.IsAny<int>()))
.Returns(houses.AsQueryable());
//...
var controller = new HouseController(mock.Object);
//Action
var response = controller.Get();
var result = response.ContentToQueryable<T>();
//Assert
Assert.AreEqual(5, result.Count());
}
That's not the correct way to use It.IsAny, which is intended to substitute a whole parameter, and not be part of one - in this case, you would use it (something) like this for an unspecified predicate:
mock.Setup(m => m.FindBy(It.IsAny<Expression<Func<int, bool>>>())
As you already know that the controller method will use the current year, use that for the setup:
mock.Setup(m => m.FindBy(f => f.Year == DateTime.Now.Year))
Then, if the controller method is accidentally changed to use the wrong value, your test will fail.
I have the following code:
var connector = new Mock<IConector>();
connector
.Setup(cn => cn.listar("FetchEstandar", new Estandar(), new {Id = 1}))
.Returns(new List<Estandar>{ new Estandar {Id = 1} });
var entidad = connector.Object
.listar("FetchEstandar", new Estandar(), new {Id = 1});
when I call listar on the connector Object, I get an "Expression Cannot Contain an Anonymouse Type" error. I've tried with rhino mocks and moq.
Is there any way I can mock this method? am I doing something wrong? alternatively, I could ignore this parameter but I don't know how. I really just need to test the value of the first parameter and ignorearguments works but I have no idea whether or how I can get this value if I use it
I do not know if this is the only way to match an anonymous object but it can be done using It.Is<>() and reflection
public class Estandar {
public int Id { get; set; }
}
public interface IConector {
IEnumerable<Estandar> listar(string name, Estandar estandar, object key);
}
[TestMethod]
public void CheckAnonymous() {
var connector = new Mock<IConector>();
connector.Setup(cn => cn.listar("FetchEstandar",
It.IsAny<Estandar>(),
It.Is<object>(it => MatchKey(it, 1))))
.Returns(new List<Estandar> { new Estandar { Id = 1 } });
var entidad = connector.Object.listar("FetchEstandar", new Estandar(), new { Id = 1 });
Assert.AreEqual(1, entidad.Count());
}
public static bool MatchKey(object key, int soughtId) {
var ret = false;
var prop = key.GetType().GetProperty("Id");
if (prop != null) {
var id = (int)prop.GetValue(key, null);
ret = id == soughtId;
}
return ret;
}