ayende / rhino-mocks Goto Github PK
View Code? Open in Web Editor NEWDynamic Mocking Framework for .NET
Home Page: http://ayende.com/
License: BSD 3-Clause "New" or "Revised" License
Dynamic Mocking Framework for .NET
Home Page: http://ayende.com/
License: BSD 3-Clause "New" or "Revised" License
When upgrading our solution from Rhino Mocks 3.5 to 3.6, several tests were broken due to a change in how Rhino Mocks creates stubs in 3.6. In 3.6, a stub will now be created using a remoting proxy if the type being stubbed is a MarshalByRefObject type. A side effect of doing this is that these remote proxy stubs lose their values when cast to (or referenced by) one of its subtypes. I encountered this because we are currently stubbing some database type objects in our tests which are MarshalByRefObject types. The following NUnit tests demonstrate the change in behavior. The tests indicate which version they apply to and assert how the behavior has changed.
Thanks for taking a look.
--matt
[TestFixture]
public class When_using_MarshalByRefObject
{
private const string Name = "@ParamterName1";
private static readonly object Value = 1;
private DbParameter dbParameter = null;
private IDbDataParameter idbParameter = null;
[SetUp]
public void SetUp()
{
dbParameter = MockRepository.GenerateStub<DbParameter>();
dbParameter.ParameterName = Name;
dbParameter.Value = Value;
idbParameter = dbParameter;
}
[Test]
public void Stub_values_missing_after_cast_in_version_36()
{
// Rhino Mocks 3.5 and 3.6 pass
Assert.AreEqual(Name, dbParameter.ParameterName);
Assert.AreEqual(Value, dbParameter.Value);
// Rhino Mocks 3.6 behavior
Assert.IsNull(idbParameter.ParameterName);
Assert.IsNull(idbParameter.Value);
}
[Test]
public void Stub_values_in_tact_after_cast_in_version_35()
{
// Rhino Mocks 3.5 and 3.6 pass
Assert.AreEqual(Name, dbParameter.ParameterName);
Assert.AreEqual(Value, dbParameter.Value);
// Rhino Mocks 3.5 behavior
Assert.AreEqual(Name, idbParameter.ParameterName);
Assert.AreEqual(Value, idbParameter.Value);
}
}
The following code will generate a runtime exception in Rhino Mocks
Previous method 'Dog.get_Active();' requires a return value or an exception to throw.
When I take Virtual off of the dog properties then the stub for my Dao just returns a newed up Dog object with default values not the one I specified.
I work around using MockRepository.GenerateStub() works however either should work really.
public class Dog
{
public virtual int Speed { get; set; }
public virtual bool Active { get; set; }
}
public interface IDogDao
{
Dog GetDog();
}
public class DogDao : IDogDao
{
public Dog GetDog() { throw new NotImplementedException(); }
}
public class MyService
{
public IDogDao DogDao { get; set; }
public void Manipulate()
{
Dog dog = DogDao.GetDog();
if (dog.Active)
{
dog.Speed++;
}
else
{
dog.Speed = 0;
}
}
}
public class MyService_test
{
[Test]
public void Manipulate_active_dog()
{
var dog = new Dog() {Active = true, Speed = 1};
var mocks = new MockRepository();
var dao = mocks.Stub();
dao.Stub(x => x.GetDog()).Return(dog);
MyService svc = new MyService() {DogDao = dao};
svc.Manipulate();
Assert.AreEqual(2, dog.Speed);
}
}
I've triggered a bug in MockRepository class. The problem is with the static dictionary generatorMap
, more precisely with following method (this is the only method that access this dictionary):
protected virtual ProxyGenerator GetProxyGenerator(Type type)
{
if (!generatorMap.ContainsKey(type))
{
generatorMap[type] = new ProxyGenerator();
}
return generatorMap[type];
}
As tests are usually run in parallel, this can lead to a NullReferenceException in the GetProxyGenerator method when accessing/inserting into the dictionary (see http://stackoverflow.com/a/2195287/699850).
PR with Fix: #24
Support something like:
MockRepository.CreateInstanceWithMockedDependencies <ClassUnderTest >()
All dependencies will be set to the mocked instances or default values (for ValueTypes and strings)
Hi*
I have the following issue when mocking interface that has a method that returns Func delegate.
Please see the following code:
public interface ITest<T>
{
Func<T> Get(string text);
}
public interface IParam
{
string Text { get; }
}
public class Param : IParam
{
public string Text { get; set; }
}
var mock = MockRepository.GenerateMock<ITest<IParam>>();
mock.Expect(m => m.Get("Test1")).Return( () => new Param { Text = "ParamWithText1" }); //OK
mock.Expect(m => m.Get("Test2")).Return( () => new Param { Text = "ParamWithText2" }); //Exception
The issue is that the fist expect runs without any problems (suppose that I commented second one) but with the second it throws InvalidCastException exception.
Unable to cast object of type
'Castle.Proxies.ProxyDelegate_Func`1_1Proxye77fc793043240708536f884e313f671' to type 'System.Func`1[IParam]'.
I tried different combination and I suspect that there are some issue with delegate but strange thing is that the first time is passes.
I would be grateful for any ideas if I'm missing something or how to solve it.
Thanks,
Norbert Raus
Given a class:
public class ListWithProperty : List<int>
{
public string MyProperty { get; set; }
}
I can create two different instances, with different properties, set an expectation for the first one, and then pass in the second one and get the response I'd set up.
var class1 = MockRepository.GenerateMock<IClass1>();
var expectedList = new ListWithProperty{MyProperty = "A value"};
class1.Expect(x => x.GetPropertyFromList(expectedList)).Return("Fake Response");
var actualList = new ListWithProperty { MyProperty = "A completely different value" };
var response = class1.GetPropertyFromList(actualList);
Assert.AreEqual("Fake Response",response);
This is due to the line in Validate.cs RecursiveCollectionEqual
if (expected is ICollection)
Which assumes that if an object is a collection and the items in the collection match then the items are the same. Which is not true in this case.
I have a test:
var controller = MockRepository.GeneratePartialMock<UserAdminController>(mockUserService, fakeContext); // mockUserService is a strict mock
controller.Expect(x => x.Update(Arg<UserDetailModel>.Matches(y => !y.IsCreate))).Return(expectedResult);
If Update is public or protected internal, the test passes. If Update is internal, I get the following exception:
System.InvalidOperationException: When using Arg, all arguments must be defined using Arg.Is, Arg.Text, Arg.List, Arg.Ref or Arg.Out. 2 arguments expected, 1 have been defined.
Something about the Version Number is wrong when I try to build Rhino.Mocks with psake:
CSC: Error CS1607: Warning as Error: Assemblygeneration -- The Productversion 3.6.0.0 / 820c1f does not follow the normal major.minor.build.revision-Format.
(I had to translate the message, but it should be clear what is meant).
greetings Daniel
When automocking a class that has a dependency on a complex generic, and the generic type is an interface, this error is raised.
e.g. automocking this class produces said error:
public class SomeClass
{
public SomeClass(IInterfaceWithGeneric<IAnotherInterface> dependency)
{
/* etc */
}
}
see also: https://groups.google.com/forum/#!topic/rhinomocks/tx7PCkQRxqs
Hi
This is an issue that has been reported before but we are getting this error in out nunit test run from Resharper. This seems to crash the second time we call dataProvider.Stub(p => p.GetDataAccessor()). There does not seem to be much difference in the arguments passed. We rebuilt rhino mocks from the latest code but now it fails although the code does not appear to have altered significantly.
var dataProvider = MockRepository.GenerateStub();
var dataConsumer = MockRepository.GenerateMock();
var calculationEngine = MockRepository.GenerateStub();
var configuration =
new AnalysisConfiguration
{
Calculations = new ICalculationInstance[0],
Switches = new IConnectionSwitch[]
{
new ConnectionSwitch
{
Name = "Switch1",
InputSelector = controlData => controlData["SwitchInput"] as string,
MissingInputIsError = false
}
},
DataConnections = new IDataConnection[]
{
new DataConnection(
new ConnectionEndPoint(PortType.Source, "Matrix2", "A"),
new ConnectionEndPoint(PortType.SwitchControl, "Switch1", "SwitchInput")),
new DataConnection(
new ConnectionEndPoint(PortType.Source, "Matrix1", "A"),
new ConnectionEndPoint(PortType.SwitchData, "Switch1", "Default")),
new DataConnection(
new ConnectionEndPoint(PortType.SwitchData, "Switch1"),
new ConnectionEndPoint(PortType.Output, "Matrix O", "Result 1")),
}
};
Func<object[]> matrix2AData = () => new object[] { "PortThatIsNotThere" };
dataProvider.Stub(p => p.GetDataAccessor("Matrix2", "A")).Return(matrix2AData);
Func<object[]> matrix1AData = () => new object[] { "DataToPassThroughSwitch" };
dataProvider.Stub(p => p.GetDataAccessor("Matrix1", "A")).Return(matrix1AData);
System.InvalidCastException : Unable to cast object of type 'ProxyDelegate_Func1_1Proxyd8161f67c1804dbd8af18811e7a851ec' to type 'System.Func
1[System.Object[]]'.
at IDataProviderProxy651fe23982b74be18df82b14e787d7f1.GetDataAccessor(String matrixID, String channelID, Boolean timeShift)
I posted this to the google group before finding this issue tracker. Rather than copying everything here, I will simply post a link to the topic in the google group. But this way the issue can be tracked with other open issues.
http://groups.google.com/group/rhinomocks/browse_thread/thread/c358e75f432d67aa#
Thanks,
--matt
May consider press Archive button in Project settings
This fails:
public class OutAttributeIssues
{
[Fact]
public void When_argument_includes_outattribute_but_is_not_a_byref_type_it_shouldnt_require_that_it_be_specified_using_ArgTOut()
{
MockRepository mocks = new MockRepository();
var theMock = mocks.StrictMock();
int expected = 30;
theMock.Expect(m => m.SomeMethod(Arg.Is.Anything)).Return(expected);
theMock.Replay();
var result = theMock.SomeMethod("test");
Assert.Equal(expected, result);
}
}
public interface IHaveAnOutAttribute
{
int SomeMethod([System.Runtime.InteropServices.OutAttribute] string someValue);
}
Removing the OutAttribute fixes the test.
The OutAttribute only sets the Out flag for the parameter, but doesn't change anything from the caller's point of view. It is only when the parameter type is a ByRef type that the signature of the method actually changes (say from string to string&).
This change fixes my test above and it doesn't break any of the others, but I can't say I know exactly what I'm doing with it, nor I have any clue how it affects the marshalling scenarios the OutAttribute is supposed to be used for:
--- a/Rhino.Mocks/ArgManager.cs +++ b/Rhino.Mocks/ArgManager.cs @@ -139,7 +139,7 @@ namespace Rhino.Mocks for (int i = 0; i < parameters.Length; i++) { - if (parameters[i].IsOut) + if (parameters[i].IsOut && parameters[i].ParameterType.IsByRef) { if (args[i].InOutRef != InOutRefArgument.OutArg) {
As followup with issue #6
The following code still throws an Exception
public interface Foo
{
Action<int> Bar(); //Action<T>, T can be of any type
}
[TestMethod]
public void TestMethod1()
{
var mock = MockRepository.GenerateMock<Foo>();
mock.Expect(e => e.Bar()).Return(x => { }); //OK
mock.Expect(e => e.Bar()).Return(x => { }); //Exception: System.InvalidCastException
}
[TestMethod]
public void TestMethod2()
{
var mock = MockRepository.GenerateMock<Foo>();
mock.Expect(e => e.Bar()).Repeat.Once().Return(x => { }); //OK
mock.Expect(e => e.Bar()).Repeat.Once().Return(x => { }); //Exception: System.InvalidCastException
}
(Sorry for the duplicate, I closed the previous one by mistake and there doesn't seem to be a way to reopen it. )
This fails:
public class OutAttributeIssues
{
[Fact]
public void When_argument_includes_outattribute_but_is_not_a_byref_type_it_shouldnt_require_that_it_be_specified_using_ArgTOut()
{
MockRepository mocks = new MockRepository();
var theMock = mocks.StrictMock();
int expected = 30;
theMock.Expect(m => m.SomeMethod(Arg.Is.Anything)).Return(expected);
theMock.Replay();
var result = theMock.SomeMethod("test");
Assert.Equal(expected, result);
}
}
public interface IHaveAnOutAttribute
{
int SomeMethod([System.Runtime.InteropServices.OutAttribute] string someValue);
}
Removing the OutAttribute fixes the test.
The OutAttribute only sets the Out flag for the parameter, but doesn't change anything from the caller's point of view. It is only when the parameter type is a ByRef type that the signature of the method actually changes (say from string to string&).
This change fixes my test above and it doesn't break any of the others, but I can't say I know exactly what I'm doing with it, nor I have any clue how it affects the marshalling scenarios the OutAttribute is supposed to be used for:
I ran into this issue trying to create a Stream mock. The Read method's buffer attribute is marked wtih the OutAttribute.
--- a/Rhino.Mocks/ArgManager.cs +++ b/Rhino.Mocks/ArgManager.cs @@ -139,7 +139,7 @@ namespace Rhino.Mocks for (int i = 0; i < parameters.Length; i++) { - if (parameters[i].IsOut) + if (parameters[i].IsOut && parameters[i].ParameterType.IsByRef) { if (args[i].InOutRef != InOutRefArgument.OutArg) {
I think that could be useful to remove an pre-defined expectation.
public void BackToRecord(object obj, BackToRecordOptions options) { this.IsMockObjectFromThisRepository(obj); if ((options & BackToRecordOptions.Expectations) == BackToRecordOptions.Expectations) { foreach (IExpectation allExpectationsForProxy in this.rootRecorder.GetAllExpectationsForProxy(obj)) { **this.rootRecorder.RemoveExpectation(allExpectationsForProxy);** } this.rootRecorder.RemoveAllRepeatableExpectationsForProxy(obj); } MockRepository.GetMockedObject(obj).ClearState(options); this.proxies[obj] = this.proxies[obj].BackToRecord(); foreach (IMockedObject dependentMock in MockRepository.GetMockedObject(obj).DependentMocks) { this.BackToRecord(dependentMock, options); } }
this.rootRecorder.RemoveExpectation(allExpectationsForProxy);
I would like to have access to the rootRecorder so I could be able to remove the expectations and set new ones.
The tests I run are "scenarios" so I don't care about how many times an method would be executed, I would like only to define the returning values and during my scenario execution the value changes. Also the system creates multiple threads during the execution so this make the testing infrastructure more complex.
Code :
public class Service{
public Service(Command[] commands) { }
}
public abstract class Command { }
var mock = MockRepository.GenerateMock<Service>(new Command[] { }); // This fails
The current expectation error message looks like this:
Rhino.Mocks.Exceptions.ExpectationViolationException:
IContestant.PlayGame("Shouldly"); Expected 1, Actual 0
Which is not super helpful. It would be better if printed close matches (or all recorded calls) like this:
Expected:
IContestant.PlayGame("Shouldly");
Recorded:
0: IContestant.PlayGame("Debugging");
1: IContestant.PlayGame("Logging");
2: IContestant.PlayGame("Drinking coffee");
3: IContestant.PlayGame("Commenting out test");
I've added this in Shouldly: http://github.com/snappycode/shouldly
If you're happy with this format or something similar I can move this to Rhino.
public interface IService
{
string Do();
}
public class RhinoTest
{
[Test]
public void Test()
{
var service = MockRepository.GenerateStub();
// in real some complex setup of bunch of mocks in separate method
service.Stub(x => x.Do()).Return("first setup");
// than I missed that service is already set up
service.Stub(x => x.Do()).Return("second setup");
var str = service.Do();
Assert.That(str == "second setup"); // fails
}
}
Is it possible at least give a warning (or even fail a test with warning) that method Do is set up twice?
public interface ITest
{
object Property{ get; set; }
void Function();
}
public class RhinoTest
{
[Test]
public void Test()
{
var mock = MockRepository.GenerateStub();
mock.Function();
mock.Property = null;
mock.AssertWasCalled(x => x.Function());
mock.AssertWasCalled(x => x.Property = null, c => c.IgnoreArguments());
}
}
Rhino.Mocks.Exceptions.ExpectationViolationException : ITest.set_Property(any); Expected #1, Actual #0.
at Rhino.Mocks.RhinoMocksExtensions.AssertWasCalled(T mock, Action1 action, Action
1 setupConstraints)
at Rhino.Mocks.RhinoMocksExtensions.AssertWasCalled(T mock, Func2 action, Action
1 setupConstraints)
at JetBrains.dotMemory.Presentation.Tests.ObjectSet.RhinoTest.Test() in RhinoTest.cs: line 22
Rhino.Mocks-3.6-Build-21
http://builds.hibernatingrhinos.com/download/715
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.