I am attempting to write a unit test for this method:
public List<Annotation> GetNotesByOrderGuid(Guid orderGuid)
{
var result = _xrmServiceContext.SalesOrderSet.Where(x => x.Id == orderGuid); //!!!!! this is returning correctly 1 record, however, it shows NULL for the list of annotations
//do some stuff and return a list of annotations
}
My unit test creates 2 notes, and attaches them to the sales order:
private XrmFakedContext _fakeContext;
[NotNull]
private IOrganizationService _fakeOrganizationService;
[Test]
public void GetNotesByOrderGuid_ExistingRecordHavingNotes_ReturnsListOfThoseNotes()
{
using (var xrmServiceContext = new XrmServiceContext(_fakeOrganizationService))
{
// Arrange
var salesOrderGuid = Guid.NewGuid();
var salesOrder = new SalesOrder { Id = salesOrderGuid };
var note1 = new Annotation
{
Id = Guid.NewGuid(),
NoteText = "this is note1",
ObjectId = new EntityReference(SalesOrder.EntityLogicalName, salesOrderGuid),
ObjectTypeCode = salesOrder.LogicalName
};
var note2 = new Annotation
{
Id = Guid.NewGuid(),
NoteText = "this is note2",
ObjectId = new EntityReference(SalesOrder.EntityLogicalName, salesOrderGuid),
ObjectTypeCode = salesOrder.LogicalName
};
_fakeContext.Initialize(new List<Entity> { salesOrder, note1, note2});
var sut = new SalesOrderService(xrmServiceContext);
// Act
// Assert
Assert.That(sut.GetNotesByOrderGuid(salesOrderGuid), Is.InstanceOf<List<Annotation>>());
}
}
[SetUp]
public void Init()
{
_fakeContext = new XrmFakedContext { ProxyTypesAssembly = Assembly.GetAssembly(typeof(SalesOrder)) };
_fakeOrganizationService = _fakeContext.GetFakedOrganizationService();
}
What am doing incorrectly in adding annotations to my entity?
The reason I ask is because when the unit tests runs this code:
var result = _xrmServiceContext.SalesOrderSet.Where(x => x.Id == orderGuid);
it shows that although there is 1 result, as there correctly should be; it shows that no annotations have been linked to it:
Related
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);
//...
Brand new both to .net core as well as for unit testing, so please be at my help pointing out where the problem lies in my code.
[TestMethod]
public void RetrieveAsync_AddModel_ReturnsNotEmptyPersonList()
{
// Arrange
var data = new List<Person>();
var mySet = new Mock<DbSet<Person>>();
var defaultHttpContext = new DefaultHttpContext();
var httpContextAccessorMock = new Mock<IHttpContextAccessor>();
httpContextAccessorMock.Setup(m => m.HttpContext).Returns(defaultHttpContext);
var myContextMock = new Mock<MyContext>(new DbContextOptions<MyContext>(), httpContextAccessorMock.Object);
myContextMock.Setup(c => c.Set<Person>()).Returns(mySet.Object);
var id = Guid.NewGuid();
var service = new PersonService(myContextMock.Object);
var model = new Person
{
Id = id
};
// Act
var createdModel = service.CreateAsync(model).Result;
data.Add(createdModel);
var findModelById = data.Find(item => item.Id == createdModel.Id).Id;
**var retrievedModel = service.RetrieveAsync(findModelById).Result; // null**
// Assert
**Assert.AreEqual(id, createdModel.Id); // correct, test passes
Assert.AreEqual(id, retrievedModel.Id); // retrievedModel is null, test fails**
}
Generics methods I have to test are as follows:
public async Task<T> CreateAsync(T model)
{
_dbContext.Set<T>().Add(model);
await _dbContext.SaveChangesAsync();
return model;
}
public async Task<T> RetrieveAsync(Guid id)
{
return await _dbContext.Set<T>().FindAsync(id);
}
The question is, why retrievedModel is null?
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 the following three methods in the CompanyApplication class (along with the supporting factories and services listed):
public ResultSet<CompanyDto> AddCompany(CompanyDto companyDto)
{
var result = new CompanyDto();
var company = new Company();
Mapper.Map(companyDto, company);
using (ITransaction t = _transactionFactory.Create())
{
company = _companyService.Add(company);
t.Commit();
}
Mapper.Map(company, result);
return new ResultSet<CompanyDto>(1, new[] { result });
}
public ResultSet<CompanyContactDto> AddCompanyContact(CompanyContactDto companyContactDto)
{
var result = new CompanyContactDto();
var company = new Company();
var contact = new CompanyContact();
Mapper.Map(companyContactDto, contact);
using (ITransaction t = _transactionFactory.Create())
{
var contactCompanies = FindByIdJoin<Company, CompanyDto>(companyContactDto.CompanySK);
Mapper.Map(contactCompanies.Data.First(), company);
company.CompanyContacts.Add(contact);
company = _companyService.Update(company);
t.Commit();
}
Mapper.Map(contact, result);
return new ResultSet<CompanyContactDto>(1, new[] { result });
}
public ResultSet<T_DtoType> FindByIdJoin<T_DbType, T_DtoType>(long id)
{
IAbstractRepository<T_DbType> repository = EnsureRepository<T_DbType>();
T_DbType entity = repository.FindByIdJoin(id);
return (entity == null ? null : MapResultSetToDto<T_DbType, T_DtoType>(entity));
}
There are other objects in play here, which is why the FindByIdJoin has been made a separate method in the CompanyApplication class.
I have set up the testing class with some mocks and an instance of the CompanyApplication class:
private Mock<ICompanyRepository> _mockCompanyRepository;
private Mock<ICompanyDomain> _mockCompanyService;
private Mock<ITransactionFactory> _mockTransactionFactory;
private Mock<ITransaction> _mockTransaction;
private CompanyApplication _companyApplication;
[Setup]
public void SetUp()
{
_mockCompanyRepository = new Mock<ICompanyRepository>(MockBehavior.Strict);
_mockCompanyService = new Mock<ICompanyDomain>(MockBehavior.Strict);
_mockTransactionFactory = new Mock<ITransactionFactory>(MockBehavior.Strict);
_mockTransaction = new Mock<ITransaction>(MockBehavior.Strict);
_companyApplication = new CompanyApplication(
_mockCompanyRepository.Object,
_mockCompanyService.Object,
_mockTransactionFactory.Object);
}
I am successfully able to test the FindByIdJoin and AddCompany methods directly in Moq like this:
[Test]
public void CanFindCompanyByIdJoin()
{
var data = new Company {ObjectId = 1, Name = "Company1"};
_mockCompanyRepository.Setup(x => x.FindByIdJoin(It.Is<long>(arg => arg == data.ObjectId)))
.Returns(data);
var result = _companyApplication.FindByIdJoin<Company, CompanyDto>(data.ObjectId);
Assert.AreEqual(data.ObjectId, result.Data.First().ObjectId);
}
[Test]
public void CanAddCompany()
{
var data = new Company {ObjectId = 1, Name = "Company1"};
_mockCompanyService.Setup(x => x.Add(It.Is<Company>(arg => arg.ObjectId == data.ObjectId)))
.Returns(data);
_mockTransactionFactory.Setup(x => x.Create()).Returns(_mockTransaction.Object);
_mockTransaction.Setup(x => x.Commit());
_mockTransaction.Setup(x => x.Dispose());
var dto = new CompanyDto {ObjectId = 1, Name = "Company1"};
var result = _companyApplication.AddCompany(dto);
_mockCompanyService.Verify(t => t.Add(It.IsAny<Company>()));
}
Those two tests pass just fine. However, I'm having trouble coming up with a test for AddCompanyContact, because it calls FindByIdJoin as part of its flow, and that seems to be getting in the way.
Specifically, is there a way to mock var contactCompanies = FindByIdJoin<Company, CompanyDto>(companyContactDto.CompanySK) in a test for the AddCompanyContact method?
Thanks!
There is two alternatives that i see depending on the amount of work that you want to do.
Wrap that call into a object and instantiate it using a IOC container. This is the one that i feel would take the most effort if you are not using one already.
Turn that call into a Func and make a method without that parameter that does the call. This approach has the disadvantage that the top call will be untestable but will allow access to the rest of the method.
Example Below:
public ResultSet<CompanyContactDto> AddCompanyContact(CompanyContactDto companyContactDto)
{
AddCompanyContact(CompanyContactDto, ()=>
{
return FindByIdJoin<Company, CompanyDto> companyContactDto.CompanySK);
}
}
public ResultSet<CompanyContactDto> AddCompanyContact(CompanyContactDto companyContactDto, Func<WhateverTheMethodReturns> findIdReplacement)
{
var result = new CompanyContactDto();
var company = new Company();
var contact = new CompanyContact();
Mapper.Map(companyContactDto, contact);
using (ITransaction t = _transactionFactory.Create())
{
var contactCompanies = findIdReplacement();
Mapper.Map(contactCompanies.Data.First(), company);
company.CompanyContacts.Add(contact);
company = _companyService.Update(company);
t.Commit();
}
Mapper.Map(contact, result);
return new ResultSet<CompanyContactDto>(1, new[] { result });
}
I was over complicating the problem... since AddCompanyContact calls FindByIdJoin, all I needed to do was mock the same interface that is used in FindByIdJoin.
Lesson learned: mock interfaces, not classes.
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;
}