Can Rhino stub out a dictionary so that no matter what key is used the same value comes back? - rhino-mocks

var fakeRoles = MockRepository.GenerateStub < IDictionary<PermissionLevel, string>>();
fakeRoles[PermissionLevel.Developer] = "Developer";
fakeRoles[PermissionLevel.DeveloperManager] = "Developer Manager";
This is specific to what that method happens to be calling, and is irrelevant for the sake of my unit test.
I'd rather do this:
fakeRoles.Stub(r => r[PermissionLevel.None]).IgnoreArguments().Return("Developer");
But I get an exception telling me to set the properties directly. Is there a way to tell rhino to just return the same value for any key given to this stub IDictionary?

What you are trying to do is not a stub (in RhinoMock's understanding), you have to create a mock:
var fakeRoles = MockRepository.GenerateMock < IDictionary<PermissionLevel, string>>();
fakeRoles.Expect(r => r[PermissionLevel.None]).IgnoreArguments().Return("Developer");

Related

Get exception when stubbing a property

When I run the following test:
[TestMethod]
public void MyTest()
{
var wizardCatalog = MockRepository.GenerateStub<IWizardCatalog>();
var firstQuestion = MockRepository.GenerateStub<IWizardQuestion>();
wizardCatalog.Stub(i => i.GetFirstQuestion()).Return(firstQuestion);
var choices = new List<IWizardChoice>();
firstQuestion.Stub(i => i.Choices).Return(choices);
}
I get this exception:
You are trying to set an expectation on a property that was defined to
use PropertyBehavior. Instead of writing code such as this:
mockObject.Stub(x => x.SomeProperty).Return(42); You can use the
property directly to achieve the same result: mockObject.SomeProperty
= 42;
Everything I read tells me that this stub operation is valid:
var choices = new List<IWizardChoice>();
firstQuestion.Stub(i => i.Choices).Return(choices);
What is going on?
PropertyBehaviour is on by default on stubs, but not on mocks. So you can either continue using a stub and change to the syntax suggested in the exception, or create a mock with GenerateMock<IWizardQuestion>() and use your existing .Stub(...).Return(...) syntax.

Cannot make Rhino Mocks return the correct type

I just started a new job and one of the first things I've been asked to do is build unit tests for the code base (the company I now work for is committed to automated testing but they do mostly integration tests and the build takes forever to complete).
So everything started nicely, I started to break dependencies here and there and started writing isolated unit tests but now I'm having an issue with rhino mocks not being able to handle the following situation:
//authenticationSessionManager is injected through the constructor.
var authSession = authenticationSessionManager.GetSession(new Guid(authentication.SessionId));
((IExpirableSessionContext)authSession).InvalidateEnabled = false;
The type that the GetSession method returns is SessionContext and as you can see it gets casted into the IExpirableSessionContext interface.
There is also an ExpirableSessionContext object that inherits from SessionContext and implements the IExpirableSessionContext interface.
The way the session object is stored and retrieved is shown in the following snippet:
private readonly Dictionary<Guid, SessionContext<TContent>> Sessions= new Dictionary<Guid, SessionContext<TContent>>();
public override SessionContext<TContent> GetSession(Guid sessionId)
{
var session = base.GetSession(sessionId);
if (session != null)
{
((IExpirableSessionContext)session).ResetTimeout();
}
return session;
}
public override SessionContext<TContent> CreateSession(TContent content)
{
var session = new ExpirableSessionContext<TContent>(content, SessionTimeoutMilliseconds, new TimerCallback(InvalidateSession));
Sessions.Add(session.Id, session);
return session;
}
Now my problem is when I mock the call to GetSession, even though I'm telling rhino mocks to return an ExpirableSessionContext<...> object, the test throws an exception on the line where it's being casted into the IExpirableSession interface, here is the code in my test (I know I'm using the old syntax, please bear with me on this one):
Mocks = new MockRepository();
IAuthenticationSessionManager AuthenticationSessionMock;
AuthenticationSessionMock = Mocks.DynamicMock<IAuthenticationSessionManager>();
var stationAgentManager = new StationAgentManager(AuthenticationSessionMock);
var authenticationSession = new ExpirableSessionContext<AuthenticationSessionContent>(new AuthenticationSessionContent(AnyUserName, AnyPassword), 1, null);
using (Mocks.Record())
{
Expect.Call(AuthenticationSessionMock.GetSession(Guid.NewGuid())).IgnoreArguments().Return(authenticationSession);
}
using (Mocks.Playback())
{
var result = stationAgentManager.StartDeploymentSession(anyAuthenticationCookie);
Assert.IsFalse(((IExpirableSessionContext)authenticationSession).InvalidateEnabled);
}
I think it makes sense the cast fails since the method returns a different kind of object and the production code works since the session is being created as the correct type and stored in a dictionary which is code the test will never run since it is being mocked.
How can I set this test up to run correctly?
Thank you for any help you can provide.
Turns out everything is working fine, the problem was that on the setup for each test there is an expectation on that method call:
Expect.Call(AuthenticationSessionMock.GetSession(anySession.Id)).Return(anySession).Repeat.Any();
So this expectation was overriding the one I set on my own test. I had to take this expectation out of the setup method, include it on a helper method and have all the other tests use this one instead.
Once out of the way, my test started working.

Rhino Mock 3.6 Repository Expected #0, Actual#1

I'm using Rhino Mock 3.6 Repository and Nhibernate. But I'm getting ExpectationViolationException Expected#0, Actual #1. I've spent two days on it. I don't know what i'm doing wrong. Here is my code. I'm getting error on mockRepository.Save(user) line.
var username = "abcdef";
var mocks = new MockRepository();
var validationResults = new ValidationResults();
IDataQuery query = mocks.StrictMock<IDataQuery>();
UserRepository mockRepository = mocks.StrictMock<UserRepository>(query);
var user = mocks.StrictMock<User>();
user.FirstName = "javed";
user.LastName = "ahmad";
user.UserName = "abc";
user.Password = "password";
user.Email = "nadeem#test.com";
user.IsActive = true;
user.CreatedBy = 1000000;
user.CreatedDate = DateTime.Today;
user.ModifiedBy = 1000000;
user.ModifiedDate = DateTime.Today;
Expect.Call(user.Validate()).Return(validationResults);
mocks.ReplayAll();
mockRepository.Save(user);
Thanks in Advance.
Thanks
Imran
You're using a StrickMock which means the only calls to be considered valid are the calls you set Expectations for. Since you didn't set an Expectation that Save would be called, you're getting an error.
Normally this means RhinoMock expects you to call user.Validate() once, but you call the method twice. You can either check that you call the method only once or change
Expect.Call(user.Validate()).Return(validationResults);
to
Expect.Call(user.Validate()).Return(validationResults).Repeat.Twice();
You appear to be mocking everything even the sut i.e. userrepository
you should be setting up mocks on interfaces that will be used inside the userrepository. you will need to pass these in to the userrepository to override their default behaviour somehow.
You need to decide what you actually want to test.
The code above implies the following to me
class UserRepository
{
public void Save(IUser user)
{
validationResult = user.Validate();
if (validationResult==null)
{
dal.Save(user);
}
}
}
That's just a guess, but the point is the code you currently have should only be mocking the user if your intention is to test that the validate method is called within the userrepository.save method

Set a property of an object in a Expect.Call

It's kind of hard to explain what I'm searching for but my example should clarify it.
I have next code:
var schedule = ScheduleUtil.CreateScheduleDto(user, user);
Expect.Call(() => _scheduleRepository.Save(schedule));
Now, what I want to do is when this Save call is made, the schedule.id property should be set to another value (1 for instance).
I do not want to mock schedule. Can this be done? The Save method doesn't return a value, so that's not a possiblity, but I do want the object schedule to be modified.
UPDATE: Maybe a small example will clarify what I exactly want.
Say there's a class with a method Save:
public void Create(Entity entity)
{
//entity is saved to database
//entity.id is updated with the created id in database
}
So, before the create, entity.id is -1, after the create it is > 0.
Now, there's a service that uses this Create. Code contracts on this service method say that before it is called, the entity must have an id equal to -1, after it is called it must have an id > 0 (preconditions and postconditions).
So, what I need is something like this:
var entity = new Entity(); //id == -1
Expect.Call(() => _instance.Create(entity);
//Now the entity.id should be a random number > 0. This is what I need, to have Rhino Mocks update the id of entity to a given integer. Is this possible?
No. If you're not mocking the _scheduleRepository, Rhino Mocks doesn't know about it. Why don't you want to mock the _scheduleRepository?
EDIT: Ok, now I see what you want to do. Use the "WhenCalled" extension method to define code to be executed when Rhino.Mocks intercepts the call. Something like this should work:
_scheduleRepository.Expect(s => s.Save(schedule)).WhenCalled(a => ((Schedule) a.Arguments[0]).Id = 1);

Rhino AutoMocker and Stubs

I am using Joshua Flanagan article “Auto mocking Explained” as a guide. In the article there is a section called “The same tests, with automocker would look like this”. I used this information to build code to run the automocker.
As you can see below answer is a list returned from the BLL. Answer does have one row in it; however, all fields are null. So the test for boo fails. Any tips and hints would be greatly appreciated.
[Test]
public void GetStaffListAndRolesByTeam_CallBLLWithDALStub()
{
// Build List<> data for stub
List<StaffRoleByTeamCV> stubData = new List<StaffRoleByTeamCV>();
StaffRoleByTeamCV stubRow = new StaffRoleByTeamCV();
stubRow.Role = "boo";
stubRow.StaffId = 12;
stubRow.StaffName = "Way Cool";
stubData.Add(stubRow);
// create the automocker
var autoMocker = new RhinoAutoMocker<PeteTestBLL>();
// get instance of test class (the BLL)
var peteTestBllHdl = autoMocker.ClassUnderTest;
// stub out call to DAL inside of BLL
autoMocker.Get<IPeteTestDAL>().Stub(c => c.GetStaffListAndRolesByTeam("4146")).Return(stubData);
// make call to BLL this should return stubData
List<StaffRoleByTeamCV> answer = peteTestBllHdl.GetStaffListAndRolesByTeam("4146");
// do simple asserts to test stubData present
// this passes
Assert.IsTrue(1 == answer.Count, "Did not find any rows");
// this fails
Assert.IsTrue(answer[0].Role == "boo", "boo was not found");
}
I tried using MockMode.AAA but still no joy
An new version of AutoMocker (1.0.3) is available. The new version supports relay mode as in this example..
[TestMethod]
public void ShouldSupportOrderedTest()
{
//Arrange
var autoMocker = new RhinoAutoMocker<CustomerUpdater>();
var mockRepository = autoMocker.Repository;
using (mockRepository.Ordered())
{
autoMocker.Get<ICustomerDataProvider>().Expect(x => x.GetCustomer(Arg<int>.Is.Anything)).Return(new CustomerItem());
autoMocker.Get<ICustomerDataProvider>().Expect(x => x.UpdateCustomer(Arg<CustomerItem>.Is.Anything));
autoMocker.Get<ILogWriter>().Expect(x => x.Write(Arg<string>.Is.Anything));
autoMocker.Get<ILogWriter>().Expect(x => x.Write(Arg<string>.Is.Anything));
autoMocker.Get<IMailSender>().Expect(x => x.SendMail(Arg<string>.Is.Anything, Arg<string>.Is.Anything));
}
//Act
autoMocker.ClassUnderTest.UpdateCustomerName(1, "Frank", "frank#somecompany.com");
//Assert
ExceptionAssert.Throws<ExpectationViolationException>(mockRepository.VerifyAll,"IMailSender.SendMail(anything, anything); Expected #1, Actual #0.\r\nILogWriter.Write(anything); Expected #1, Actual #0.\r\n");
}
I haven't tried, but this article suggests that by default all the mocks created by automocker are not replayed:
http://www.lostechies.com/blogs/joshuaflanagan/archive/2008/09/25/arrange-act-assert-with-structuremap-rhinoautomocker.aspx
Yes that was true for the previous version. But was changed to support ordered tests in version 1.0.3.