In this post, i will be showing how you can mock property sets with your expected values or even action using JustMock. To begin, we have a sample interface:
- public interface IFoo
- {
- int Value { get; set; }
- }
Now, we can create a mock that will throw on any call other than the one expected, generally its a strict mock and we can do it like:
- bool expected = false;
- var foo = Mock.Create<IFoo>(BehaviorMode.Strict);
- Mock.ArrangeSet(() => { foo.Value = 1; }).DoInstead(() => expected = true);
-
- foo.Value = 1;
-
- Assert.True(expected);
Here , the method for running though our expectation for set is Mock.ArrangeSet , where we can directly set our expectations or can even set matchers into it like:
- var foo = Mock.Create<IFoo>(BehaviorMode.Strict);
-
- Mock.ArrangeSet(() => foo.Value = Arg.Matches<int>(x => x > 3));
-
- foo.Value = 4;
- foo.Value = 5;
-
- Assert.Throws<MockException>(() => foo.Value = 3);
In the example, any set for value not satisfying matcher expression will throw an MockException as this is a strict mock but what will be the case for loose mocks, where we also have to assert it. Here, let’s take an interface with an indexed property. Indexers are treated in the same way as properties, as with basic indexers let you access your class if it were an array.
- public interface IFooIndexed
- {
- string this[int key] { get; set; }
- }
We want to setup a value for a particular index, we then will pass that mock to some implementer where it will be actually called. Once done, we want to assert that if it has been invoked properly.
- var foo = Mock.Create<IFooIndexed>();
-
- Mock.ArrangeSet(() => foo[0] = "ping");
-
- foo[0] = "ping";
-
- Mock.AssertSet(() => foo[0] = "ping");
In the above example, both the values are user defined, it might happen that we want to make it more dynamic, In this example, i set it up for set with any value and finally checked if it is set with the one i am looking for.
- var foo = Mock.Create<IFooIndexed>();
-
- Mock.ArrangeSet(() => foo[0] = Arg.Any<string>());
-
- foo[0] = "ping";
-
- Mock.AssertSet(() => foo[0] = Arg.Matches<string>(x => string.Compare("ping", x) == 0));
This is more or less of mocking user sets , but we can further have it to throw exception or even do our own task for a particular set , like :
- Mock.ArrangeSet(() => foo.MyProperty = 10).Throws(new ArgumentException());
Or
- bool expected = false;
- var foo = Mock.Create<IFoo>(BehaviorMode.Strict);
- Mock.ArrangeSet(() => { foo.Value = 1; }).DoInstead(() => expected = true);
-
- foo.Value = 1;
-
- Assert.True(expected);
Or call the original setter , in this example it will throw an NotImplementedExpectation
- var foo = Mock.Create<FooAbstract>(BehaviorMode.Strict);
- Mock.ArrangeSet(() => { foo.Value = 1; }).CallOriginal();
- Assert.Throws<NotImplementedException>(() => { foo.Value = 1; });
Finally, try all these, find issues, post them to forum and make it work for you :-).
Hope that helps,