For some objects I want to create default stubs so that common properties contains values. But in some cases I want to override my default behaviour. My question is, can I somehow overwrite an already stubbed value?
//First I create the default stub with a default value
var foo = MockRepository.GenerateStub<IFoo>();
foo.Stub(x => x.TheValue).Return(1);
//Somewhere else in the code I override the stubbed value
foo.Stub(x => x.TheValue).Return(2);
Assert.AreEqual(2, foo.TheValue); //Fails, since TheValue is 1
Using Expect instead of Stub and GenerateMock instead of GenerateStub will solve this:
//First I create the default stub with a default value
var foo = MockRepository.GenerateMock<IFoo>();
foo.Expect(x => x.TheValue).Return(1);
//Somewhere else in the code I override the stubbed value
foo.Expect(x => x.TheValue).Return(2);
Assert.AreEqual(1, foo.TheValue);
Assert.AreEqual(2, foo.TheValue);
Related
I need some clarification on how exactly the instance whos property is being validated, is passed down to each validator in a rule.
Let's assume the following:
RuleFor(x => x.MyProperty).SetValidator(new MyCustomValidator()).NotNull();
The MyCustomValidator will set a value on MyProperty if the value is NULL in some cases.
I would expect that the NotNull validation would pass.
However, it appears this is not the case.
When I split up the RuleFor into two seperate calls:
RuleFor(x => x.MyProperty).SetValidator(new MyCustomValidator());
RuleFor(x => x.MyProperty).NotNull();
it works as expected.
But of course, i'd like to avoid having multiple "RuleFor" statements for the same property
This makes me believe that at the start of the "RuleFor", the instance and/or property value being validated is cached/copied and then provided to each validator specified for that rule.
I've also created a fiddle demonstrating this behaviour here: https://dotnetfiddle.net/rDTrDU
The chained one will create one PropertyRule with multiple components and when they are processed FluentValidation caches property value and uses it for every component:
var accessor = new Lazy<TProperty>(() => PropertyFunc(context.InstanceToValidate), LazyThreadSafetyMode.None);
The not chained one creates multiple PropertyRules with one component so after the first rule is validated the MyObject instance will be modified and property accessor will use the new value.
In your case I would try to use PreValidate in MyObjectValidator:
public class MyObjectValidator : AbstractValidator<MyObject>
{
protected override bool PreValidate(ValidationContext<MyObject> context, ValidationResult result)
{
var version = context.RootContextData["SourceVersion"] as Version;
if (version < new Version(2, 0, 0) && string.IsNullOrWhiteSpace(context.InstanceToValidate.MyProperty))
{
Console.WriteLine("\t[DEBUG]: Setting value to 'Hello world'");
context.InstanceToValidate.MyProperty = "Hello world";
}
return true;
}
....
}
I read a few tutorial on Moq C# package but I still can't really understand what is Setup and Returns in Moq.
Example,
mock.Setup(p => p.GetEmployeebyId(1)).ReturnsAsync("JK");
Example 2,
mock.Setup(x => x.Save(It.IsAny<DeskBooking>())).Callback<DeskBooking>(
deskBooking =>
{
savedDeskBooking = deskBooking;
});
)
TL;DR: Setup = When, Returns = What
Whenever you write unit tests then you want make sure that a given piece of functionality is working as expected. But most of the time the functionality depends on some other components / environment / external source / whatsoever.
To make your test focused and replayable we need to use test doubles. These will replace your dependencies during the test. We can categorize the test doubles like this:
Dummy: simple code that returns bogus data
Fake: a working alternative which can take shortcuts
Stub: custom logic with predefined data
Mock: custom logic with expectations (interactive stub)
Shim: custom logic at run-time (replace static with a delegate)
Spy: interceptors to record calls
So, whenever you want to create a mock then you have to tell that under what circumstances how should the component behave. In other words when the function is called with a particular input then what should be the expected output.
In case of Moq you can use the Setup to define the when. And the Returns to specify the what.
Here is a simple example. Let's suppose you have the following function:
private IService service;
string MyMethod()
{
int number = service.GetNextNumber();
if(number % 2 == 0)
{
return "even";
}
else
{
return "odd";
}
}
Then you can write the following to test cases:
public void GivenAnEvenNumber_WhenICallMyMethod_ThenItShouldReturnEven
{
//Arrange
var serviceMock = new Mock<IService>();
serviceMock
.Setup(svc => svc.GetNextNumber())
.Returns(2);
...
//Act
var result = SUT.MyMethod();
//Assert
Assert.Equal("even", result);
}
public void GivenAnOddNumber_WhenICallMyMethod_ThenItShouldReturnOdd
{
//Arrange
var serviceMock = new Mock<IService>();
serviceMock
.Setup(svc => svc.GetNextNumber())
.Returns(1);
...
//Act
var result = SUT.MyMethod();
//Assert
Assert.Equal("odd", result);
}
So, as you can see we have used Setup and Returns to direct the control flow in each test case.
Your second example can be considered a Spy, because there you are recording the input for latter assessment.
In example 1
mock.Setup(p => p.GetEmployeebyId(1)).ReturnsAsync("JK");
sets up your mock so when GetEmployeebyId is called with a 1 as the parameter, the mock will return "JK".
In example 2
mock.Setup(x => x.Save(It.IsAny<DeskBooking>())).Callback<DeskBooking>(
deskBooking =>
{
savedDeskBooking = deskBooking;
});
when the Save method is called with any parameter of type DeskBooking, the lambda function will save the parameter in the savedDeskBooking variable. You can then test that you've saved the DeskBooking you expected.
I'm going to simplify a bit the problem:
In my tests, I use a mocked object (I mocked it because it calls a bdd) which I give in parameters to a method of another object (not mocked) whose purpose is to modify a property of this mocked object.
ModifyingClass myModifyingClass = new ModifyingClass();
Mock<ToModifyClass> mockedClass = new Mock<ToModifyClass>();
mockedClass.Setup(mc => mc.name).Returns("Test1");
myModifyingClass.modify(mockedClass.Object);
The method modify then try to set the property name of the mocked object, but it won't work, so maybe it's the normal behavior but I really need to test if all of this work and if the method modify set the property as I want.
As mentioned in the comments you need to setup the mocked class differently in order to retain the values passed to properties.
Reference Moq - Quickstart
Stub all properties on a mock (not available on Silverlight):
mock.SetupAllProperties();
The example test provided would then look like...
//Arrange
var myModifyingClass = new ModifyingClass();
var mockedClass = new Mock<ToModifyClass>();
mockedClass.SetupAllProperties(); //<-- this will allow property changes to be retained.
var model = mockedClass.Object;
//set the property now that it can be set
model.name = "Test1";
var expected = "expected value here";
//Act
myModifyingClass.modify(model);
//Assert
var actual = model.name;
Assert.AreEqual(expected, actual);
//... other assertions
In Moq one would need to setup the getter.
mockedClass.SetupGet(mc => mc.name).Returns("Test1");
I'm trying to write a parameterized unit test using NUnit and Rhino Mocks that can return true or false depending on whether a certain mocked method was called. AssertWasCalled is not right because it makes the test fail right away. I only want a bool value.
[Test]
[TestCase(1,2, Result=false)]
[TestCase(1,1, Result=true)]
public bool SomeTest(int a, int b)
{
...
someObject.CheckValues(a, b); // logs something if values are different.
return mockLogger.WasCalled(x => x.Log(null));
}
WasCalled ofc does't exist.
Stub the Log method on mockLogger to set a bool when it's called, and return that:
bool logMethodWasCalled = false;
mockLogger
.Stub(x => x.Log(Arg<string>.Is.Equal(null))
.Do(new Action<string>(_ => logMethodWasCalled = true));
// Run test...
return logMethodWasCalled;
It's better to use expectation:
mockLogger.Expect(x => x.Log(Arg<string>.Is.Anything));
mockLogger.VerifyAllExpectations();
If you want to check if parameter is null use:
mockLogger.Expect(x => x.Log(Arg<string>.Is.Null));
Another way is to use:
triggerManagerMock.AssertWasCalled(x => x.Log(Arg<string>.Is.Anything));
It that case you can use Stub method to model behavior and AssertWasCalled to check the call.
I'm having trouble figuring out how to set indexers in C# with Moq. The Moq documentation is weak, and I've done a lot of searching... what I'd like to do is similar in the solution to How to Moq Setting an Indexed property:
var someClass = new Mock<ISomeClass>();
someClass.SetupSet(o => o.SomeIndexedProperty[3] = 25);
I want to modify the above to work for any index and any value so I can just do something like this:
someClass.Object.SomeIndexedProperty[1] = 5;
Currently I have the following, which works great for the indexed property getter, but if I ever set the value Moq ignores it:
var someValues = new int[] { 10, 20, 30, 40 };
var someClass = new Mock<ISomeClass>();
someClass.Setup(o => o.SomeIndexedProperty[It.IsAny<int>()])
.Returns<int>(index => someValues[index]);
// Moq doesn't set the value below, so the Assert fails!
someClass.Object.SomeIndexedProperty[3] = 25;
Assert.AreEqual(25, someClass.Object.SomeIndexedProperty[3]);
I found a solution to my problem. It requires a shift in my thinking... I had been looking to use NUnit's Assert to verify that the indexer setter in my someClass mock was being called with the correct value.
It seems that with Moq the supported way to do this is to use the VerifySet function. A contrived example:
someClass.Object.SomeIndexedProperty[3] = 25;
someClass.VerifySet(mock => mock.SomeIndexedProperty[3] = 25);
The unit test passes since SomeIndexedProperty[3] is set to 25, but would fail otherwise.
Using Moq 3.1.416.3
Setup won't work for indexers (because it takes an expression which means assignment statements are ruled out)
so you need to use SetupSet like
_settingsStore.SetupSet(store => store["MruNotes"] = It.IsAny<string>())
.Callback<string,string>( (key, value) => persistedValue = value);
A small caveat:
this expression only matches if the key is "MruNotes". I was not able to use a matcher like It.IsAny for the key.
In your test your only set expectations for the getter of the indexer - and this will always return the corresponding value from your array. The indexer doesn't behave like a real thing. You can try a few things to have it fixed:
You can check if you can stub this indexer. I am personally using RhinoMocks, so I have no idea if this is implemented
someClass.SetupProperty(f => f.SomeIndexedProperty);
You can try to mock the setter as well and make it to change the underlying array. My first guess would be to try something along these lines (no guarantee it will work):
someClass.Setup(o => o.SomeIndexedProperty[It.IsAny<int>()] = It.IsAny<int>())
.Callback((index, value) => someValues[index] = value);
Or if the ISomeClass interface is small enough, you could just created a stub implementation yourself (that would have the indexer implemented as a dictionary, array etc.)