Moq.Setup not returning expected collection? - c#

I have the following code:
var service = new Mock<INavigationService>();
service.Setup(x => x.GetSchemes(new SchemeFilterEntity())).Returns(new List<SchemeEntity>
{
new SchemeEntity
{
Id = 1,
Name = "Test"
},
new SchemeEntity
{
Id = 2,
Name = "Test 2"
}
});
var sut = service.Object;
var sut = service.GetSchemes(new SchemeFilterEntity());
However when the GetSchemes method is called it returns null?
Any ideas?

I believe that should be
service.Setup(x => x.GetSchemes(It.IsAny< SchemeFilterEntity >())).Returns.....
because otherwise, moq will be looking for that exact instance of the 'new SchemeFilterEntity()' that you passed in in the setup method, which will never match anything else.
Edit: That said, your sut should not be the thing you are mocking, it should be the thing that's using your mocked object.

I don't know what you are tring to test but if you want "Override" the behavior of GetSchema
using a mocked object that method must be virtual on the class
If you want to use the mocked object to stub out the INavigationService you have to do the below
.........
var sut = service.Object;
SomeThing.UseNavigavtionService(sut); //this is supposed to be the class which you will test.Sut is a mocked INavigationService
in your setup you should also use It.IsAny< SchemeFilterEntity >() instead of create a concrete object

Related

How to setup Mock to already present object as defaul behavior?

I can do this:
var alreadyPresentMyClass = GetMyClass();//retrieving MyClass from somewhere
var mock = new Mock<IMyClass>();
mock.Setup(x=> x.Method1()).Callback(alreadyPresentMyClass.Method1);
mock.Setup(x=> x.Method2()).Callback(alreadyPresentMyClass.Method2);
....
mock.Setup(x=> x.Method666()).Throws(new Exception("BAD LUCK")); //this is only method which is throwing error in this test. So the only one I want to setup.
....
mock.Setup(x=> x.Method1000()).Callback(alreadyPresentMyClass.Method1000);
How one can remove unnecessary garbage of setuping thousands of methods, and instead setup it based on another object as default, like this:
var mock = Mock.CreateByAlreadyPresent(GetMyClass());
mock.Setup(x=> x.Method666()).Throws(new Exception("BAD LUCK"));
Any thoughts? I can write reflection method myself, but is there already such method?
You would use the property CallBase for that:
var mock = new Mock<MyClass> { CallBase = true };
mock.Setup(x => x.Method666()).Throws(new Exception("BAD LUCK"));
The other methods will have their default behaviour.

Is it a good practice to mock Automapper in unit tests?

There is this codebase where we use automapper and have 2 layers, Domain and Service. Each has its object for data representation, DomainItem and ServiceItem. The service gets data from domain, the uses constructor injected automapper instance to map
class Service
{
public ServiceItem Get(int id)
{
var domainItem = this.domain.Get(id);
return this.mapper.Map<DomainItem, ServiceItem>(domainItem);
}
}
Assume best practices, so mapper has no side-effects and no external dependencies. You'd write a static function to convert one object to another within seconds, just mapping fields.
With this in mind, is it a good practice to mock the mapper in unit tests like this?
[TestClass]
class UnitTests
{
[TestMethod]
public void Test()
{
var expected = new ServiceItem();
var mockDomain = new Mock<IDomain>();
// ... setup
var mockMapper = new Mock<IMapper>();
mockMapper.Setup(x => x.Map<DomainItem, ServiceItem>(It.IsAny<DomainItem>()))
.Returns(expected);
var service = new Service(mockDomain.Object, mockMapper.Object);
var result = service.Get(0);
Assert.AreEqual(expected, result);
}
}
To me, it seems that such unit test does not really bring any value, because it is effectively testing only the mocks, So i'd either not write it at all OR I'd use the actual mapper, not the mocked one. Am I right or do I overlook something?
I think the issue here is that the test is badly written for what it is actually trying to achieve which is testing Service.Get().
The way I would write this test is as follows:
[TestMethod]
public void Test()
{
var expected = new ServiceItem();
var mockDomain = new Mock<IDomain>();
var expectedDomainReturn = new DomainItem(0); //Illustrative purposes only
mockDomain.Setup(x => x.DomainCall(0)).Returns(expectedDomainReturn); //Illustrative purposes only
var mockMapper = new Mock<IMapper>();
mockMapper.Setup(x => x.Map<DomainItem, ServiceItem>(It.IsAny<DomainItem>()))
.Returns(expected);
var service = new Service(mockDomain.Object, mockMapper.Object);
var result = service.Get(0);
mockDomain.Verify(x => x.DomainCall(0), Times.Once);
mockMapper.Verify(x => x.Map<DomainItem, ServiceItem>(expectedDomainReturn), Times.Once);
}
This test instead of not really checking the functionality of the service.Get(), checks that the parameters passed are correct for the individual dependency calls based on the responses. You are thus not testing AutoMapper itself and should not need to.
Checking result is basically useless but will get the code coverage up.

How to test new Object within a function using RhinoMocks and mbunit

I am trying to test the below method using RhinoMocks and MbUnit however I am unable to get the test to pass. The current error is when the expect call for "" is not found.
The function is in vb.net and the test is in c#
Public Function Login(user As Website.BusinessObjects.User) As Integer Implements IActivityLog.Login
Dim item As BOAudit.IActivityLog = New BOAudit.ActivityLog(_request)
' Activity
item.UserID = User.GuidID
item.Type = Enums.ActivityType.Login
item.Description = String.Format(If(IsAdmin, "Logged in as {0}", "Logged in"), User.FullName)
item.EventUserID = _authenticatedUser.GuidID
Return _dalActivityLog.Save(item)
End Function
The test below is what I currently have and I believe the issue is down to declaring a new object within the function above and not passing that object into the function. What is the best way to test the above function and should I be passing in the object?
[Test]
public void Login_Data_NewRecordCreated()
{
const int id = 99;
var data = new Website.CodeModules.BusinessObjects.Audit.ActivityLog(_request)
{
Type = Enums.ActivityType.Login,
Description = "Logged in",
EventUserID = _user.GuidID
};
var user = _mocks.StrictMock<User>();
using (_mocks.Record())
{
Expect.Call(_dalActivityLog.Save(data)).Return(id);
}
using (_mocks.Playback())
{
var result = _balActivityLog.Login(user);
Assert.AreEqual(id, result);
}
}
The condition you assert in your test does not seem to have much sense. Your code seems to test that the mock instance in _dalActivityLog returns the constant that you've set up.
In that test you should test the code of the function Login, not the _dalActivityLog implementation. Thus, you should check that _dalActivityLog.Save is called with the right parameter passed.
I suppose that _dalActivityLog is an instance of a class that implements an interface that you haven't specified in your question. Let's call it IActivityLog. Then you should set up a mock instance of it in your test code.
IActivityLog logMock = MockRepository.GenerateStub<IActivityLog>();
Then you inject somehow this mock instance into the instance of the class the has the Login method (via constructor or property).
Then call your Login method and pass there an instance of User.
Then you make the assertion about the _dalActivityLog.Save call, like the one below.
logMock.AssertWasCalled(
call => call.Save(
Arg<Website.CodeModules.BusinessObjects.Audit.ActivityLog>.Matches(
logItem => logItem.UserID == user.GuidID && logItem.Type == Enums.ActivityType.Login
)
)
);

How do I get arguments passed to a data access layer that uses System.Action as an input parameter?

I'm trying to create some unit tests for an application I've recently inherited. Currently using NSubstitute because that's what the previous programmer used, but I'm not attached to it.
The method I'm testing calls the DataService class' Create method.
Calling Create Method
var contactProductLink = this.dsService.Create<ContactProductLink>(x =>
{
x.ContactRoleId = prod.RoleId;
x.ContactId = contactViewModel.ContactId;
x.ProductId = prod.ProductId;
x.Active = true;
x.InsertDate = DateTime.Now;
x.InsertUserId = user.employeeId;
x.UpdateDate = DateTime.Now;
x.UpdateUserId = user.employeeId;
});
DataService Create Method:
public TEntity Create<TEntity>(Action<TEntity> propertySetter = null) where TEntity : class
{
var tEntity = this.Context.Create<TEntity>();
if (propertySetter != null)
{
propertySetter(tEntity);
}
return tEntity;
}
The approach I've taken (and maybe there's a better way) is to use NSubstitute to mock the DataService. When I'm doing my assertions at the end, I'm checking to make sure that the Create method was called:
mockDataSupplierService.Received().Create<ContactProductLink>(Arg.Any<Action<ContactProductLink>>());
However, I'd like to also verify the input that was sent to the method is correct, and here's where I'm running into trouble. I can get the System.Action object that was passed to the Create method, but I can't figure out how to pull out the parameters (such as ContactRoleId, ContactId, etc. as posted in the calling create method code snippet).
So after all of that what I'm asking is:
How can I access those input parameters so I can verify the correct arguments are being passed to the data service? Is it even possible?
Is there a better way to do this than what I'm currently trying to do?
Solution
//Arrange
mockDataSupplierService.Create<ContactProductLink>(Arg.Do<Action<ContactProductLink>>(x=> actionToPopulateEntity = x));
//Assert
mockDataSupplierService.Received().Create<ContactProductLink>(Arg.Any<Action<ContactProductLink>>());
var entity = new ContactProductLink();
actionToPopulateEntity.Invoke(entity);
Assert.AreEqual(ExpectedContactId, entity.ContactId);
How can I access those input parameters so I can verify the correct arguments are being passed to the data service? Is it even possible?
Essentially you can't, as it is not possible to extract "code" details from action (consider what happens when you pass an action that doesn't set any properties - this is totally legal, but would break hypothetical mechanism).
However, you can try this instead:
Create entity with initial values
Use Arg.Invoke argument, telling NSubstitute to use chosen object as action parameter
Verify that entity properties values changed
For example:
// Arrange
var entity = new ContactProductLink
{
ContactRoleId = // ...
// ...
};
mockDataSupplierService
.Create<ContactProductLink>(Arg<ContactProductLink>.Invoke(entity));
// Act
// ...
Assert.That(entity.ContactRoleId, Is.EqualTo(2));
// ...

Mocking an attribute change on a parameter - using Moq

I am using Moq to mock my Repository layer so I can unit test.
My repository layer Insert methods update the Id property of my entities when a successful db insert occurs.
How do I configure moq to update the Id property of the entity when the Insert method is called?
Repository code:-
void IAccountRepository.InsertAccount(AccountEntity account);
Unit Test:-
[TestInitialize()]
public void MyTestInitialize()
{
accountRepository = new Mock<IAccountRepository>();
contactRepository = new Mock<IContactRepository>();
contractRepository = new Mock<IContractRepository>();
planRepository = new Mock<IPlanRepository>();
generator = new Mock<NumberGenerator>();
service = new ContractService(contractRepository.Object, accountRepository.Object,
planRepository.Object, contactRepository.Object, generator.Object);
}
[TestMethod]
public void SubmitNewContractTest()
{
// Setup Mock Objects
planRepository
.Expect(p => p.GetPlan(1))
.Returns(new PlanEntity() { Id = 1 });
generator
.Expect(p => p.GenerateAccountNumber())
.Returns("AC0001");
// Not sure what to do here?
// How to mock updating the Id field for Inserts?
//
// Creates a correctly populated NewContractRequest instance
NewContractRequest request = CreateNewContractRequestFullyPopulated();
NewContractResponse response = service.SubmitNewContract(request);
Assert.IsTrue(response.IsSuccessful);
}
implementation snippet from ContractService class (WCF service contract).
AccountEntity account = new AccountEntity()
{
AccountName = request.Contact.Name,
AccountNumber = accountNumber,
BillingMethod = BillingMethod.CreditCard,
IsInvoiceRoot = true,
BillingAddressType = BillingAddressType.Postal,
ContactId = request.Contact.Id.Value
};
accountRepository.InsertAccount(account);
if (account.Id == null)
{
// ERROR
}
I apologise if this information may be a little lacking. I only started learning moq and mocking frameworks today. ac
You can use the Callback method to mock side-effects. Something like:
accountRepository
.Expect(r => r.InsertAccount(account))
.Callback(() => account.ID = 1);
That's untested but it's along the right lines.
I'm not sure how that will work because account is created inside the method, so it's not the instance I'll be referring to when I set the value of ID to 1.
Perhaps there's a flaw in my design and I should be checking for ID > 0 inside the IAccountRepository.InsertAccount implementation and then returning a bool if it's ok. Though then I've a problem with inserting an account that has a related object that needs to be insterted (and an Id genereated).
I found this to be the answer to my problem
accountRepository
.Expect(p => p.InsertAccount(It.Is<AccountEntity>(x => x.Id == null)))
.Callback<AccountEntity>(a => a.Id = 1);
thanks.

Categories

Resources