0

我已将行为隔离到以下测试用例中。我会感谢任何能告诉我如何期待/验证属性集的人List<T>- 似乎里面发生了一些事情,It.Is<T>(predicate)现在对我来说没有多大意义。示例代码将作为 VS2008 中的控制台应用程序运行 - 您需要添加对 Moq 2.6 的引用(我在 2.6.1014.1 上) - 请尝试取消注释不同的 ExpectSet 语句以查看发生了什么...

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);
            }
        }
    }
}
4

4 回答 4

1

ExpectSet() 的第二个参数是您期望的值。您不能It.Is<T>在这种情况下使用,因为没有采用谓词的重载 - 尽管它会很好;)这是您的示例的(简化)摘录,说明了值的使用:

var mockView = new Mock<IView>();
var list = new List<string> { "Hugh", "Pugh", "Barney McGrew" };

mockView.ExpectSet(mv => mv.Names, list);

mockView.Object.Names = list;

希望有帮助。

编辑:修正错字。

于 2008-12-11T01:27:37.827 回答
1

我没有使用最新版本的 Moq,所以我没有使用两个参数的 ExpectSet 重载,但我在这种模式上取得了一些成功:

mockView.ExpectSet(mv => mv.Names).Callback(n => Assert.That(n != null));

如果分配给 .Names 的值与谓词不匹配,回调中的 Assert(来自 NUnit)调用将引发异常。但是,当测试失败时,它确实很难追踪。我同意将 It.Is 或 It.IsAny 作为第二个参数传递的能力会很方便。

于 2008-12-11T01:53:37.900 回答
1

顺便说一句,ExpectSet 不支持 It.Is。您的代码编译只是因为它们在用作值(而不是表达式)时是常规方法调用,而在 Expect表达式中使用时,它们由 Moq 预处理并赋予特定含义(而不是所有它的 null/默认值.Is 成员实际上返回)。

您可以在给定属性 (mockView.Stub(mv => mv.Names)) 上使用存根行为,然后在执行后直接断言其值。

于 2009-01-03T21:24:43.127 回答
0

Moq 不提供接收 It.IsAny 的重载,因为它实际上与在不传递预期值的情况下调用 ExpectSet 相同;)

于 2009-01-03T21:17:11.877 回答