I’ve isolated the behaviour into the following test case. I’d be grateful to anyone who can tell me how to expect/verify a property set for a List<T> property – it appears there’s something going on inside It.Is<T>(predicate) that isn’t making a whole lot of sense to me right now. Sample code will run as a console app from VS2008 – you’ll need to add a reference to Moq 2.6 (I’m on 2.6.1014.1) – please try uncommenting the different ExpectSet statements to see what’s happening…
using System; using Moq; using System.Collections.Generic; namespace MoqDemo { public interface IView { List<string> Names { get; set; } } public class Controller { private IView view; public Controller(IView view) { this.view = view; } public void PopulateView() { List<string> names = new List<string>() { 'Hugh', 'Pugh', 'Barney McGrew' }; view.Names = names; } public class MyApp { public static void Main() { Mock<IView> mockView = new Mock<IView>(); // This works - and the expectation is verifiable. mockView.ExpectSet(mv => mv.Names); // None of the following can be verified. // mockView.ExpectSet(mv => mv.Names, It.Is<Object>(o => o != null)); // mockView.ExpectSet(mv => mv.Names, It.Is<List<string>>(names => names.Count == 3)); // mockView.ExpectSet(mv => mv.Names, It.IsAny<IList<String>>()); Controller controller = new Controller(mockView.Object); controller.PopulateView(); try { mockView.VerifyAll(); Console.WriteLine('Verified OK!'); } catch (MockException ex) { Console.WriteLine('Verification failed!'); Console.WriteLine(ex.Message); } Console.ReadKey(false); } } } }
I’m not using the very latest version of Moq, so I don’t have an overload of ExpectSet that takes two parameters, but I’ve had some success with this pattern:
The Assert (from NUnit) call in the callback will throw an exception if the value assigned to .Names doesn’t match the predicate. It does make it hard to trace when a test fails, though. I agree that the ability to pass an It.Is or It.IsAny as the second parameter would be handy.