The new release candidate for SpecsFor adds some new capabilities for both Looks.Like and ShouldLookLike. Read on to find out more!
[more]
First, Looks.Like now supports strongly-typed partial matching using lambda expressions, just like ShouldLookLike:
public class when_verifying_with_a_partial_object : SpecsFor<object> { [Test] public void then_it_verifies_correctly_if_the_object_matches_the_specified_properties() { var myCar = new TrainCar {Name = "Simple Car", MaxPassengers = 100, YearBuilt = 2014}; GetMockFor<ITrainYard>().Object .StoreCar(myCar); GetMockFor<ITrainYard>() .Verify(x => x.StoreCar(Looks.Like(() => new TrainCar{YearBuilt = 2014}))); } }
Second, you can now combine partial matching with Moq’s matchers to handle even more complex scenarios. For example, checking that a DateTime property was “recent” (as in within the past second or two) was difficult to do with ShouldLookLike and Looks.Like. Now, it’s easy!
public class when_partially_comparing_a_simple_object : SpecsFor<object> { [Test] public void then_the_objects_are_equal_if_the_matcher_is_satisfied() { var person = new Person { FirstName = "John", LastName = "Smith" }; person.ShouldLookLike(() => new Person { LastName = It.Is<string>(s => s.StartsWith("S")) }); } } public class when_verifying_with_a_partial_object : SpecsFor<object> { [Test] public void then_it_verifies_correctly_if_the_matcher_is_satisfied() { GetMockFor<ITrainYard>().Object .RetrieveLuggage(new LuggageTicket { IssuedTo = "Jane Doe", Issued = DateTime.Now, }); GetMockFor<ITrainYard>() .Verify(x => x.RetrieveLuggage(Looks.Like(() => new LuggageTicket { IssuedTo = "Jane Doe", Issued = It.Is<DateTime>(d => DateTime.Now.Subtract(d) < TimeSpan.FromSeconds(1)) }))); } }
Now, the ability to use Moq’s matchers is risky. I feel like I’m getting deeper into Moq’s internals than is reasonable. Therefore, the syntax for this *might* change, and SpecsFor may implement its own custom matchers that are analogous to what Moq provides. While I do like having a single way to write matchers when creating specs using SpecsFor, I’m leaning towards going the later route just for the sake of cleaner code. If you have any thoughts or ideas, please share in the comments!