使用WinForms MVP模式的Moq-测试失败

使用WinForms MVP模式的Moq-测试失败,winforms,tdd,moq,mvp,Winforms,Tdd,Moq,Mvp,我正在学习TDD和MVP模式。我创建了一个简单的WinForms应用程序,类似于TOAD SQL工具的替代品。我现在正试图回去为我已经编写的代码编写测试(我知道这不是TDD的正确过程,但请耐心等待) 在我的表单测试类中,我想测试具体的Presenter,但是模拟WinForm,因为Presenter中有应该测试的真正逻辑。然而,当我使用Moq模拟视图时,我没有看到预期的结果。在下面的代码中,前两个测试通过,但第三个测试在第一次断言时失败 当我将调试器附加到NUnit并运行时,Environmen

我正在学习TDD和MVP模式。我创建了一个简单的WinForms应用程序,类似于TOAD SQL工具的替代品。我现在正试图回去为我已经编写的代码编写测试(我知道这不是TDD的正确过程,但请耐心等待)

在我的表单测试类中,我想测试具体的
Presenter
,但是模拟WinForm,因为Presenter中有应该测试的真正逻辑。然而,当我使用Moq模拟视图时,我没有看到预期的结果。在下面的代码中,前两个测试通过,但第三个测试在第一次断言时失败

当我将调试器附加到NUnit并运行时,
Environment
属性未设置为
Environments.Test
当调用
presenter.isDangerusSQL
时:

private Mock<IQueryForm> mockWindow;
private QueryFormPresenter presenter;

/// <summary>
/// Runs ONCE prior to any tests running
/// </summary>
[TestFixtureSetUp]
public void TestFixtureSetUp()
{
    //We're interested in testing the QueryFormPresenter class here, but we 
    //don't really care about the QueryForm window (view) since there is hardly any code in it.
    //Therefore, we create a mock of the QueryForm view, and pass it to the QueryFormPresenter to use.
    mockWindow = new Mock<IQueryForm>();
    presenter = new QueryFormPresenter(mockWindow.Object);
}

[Test]
public void User_Can_Execute_Selects_From_Any_Environment()
{
    Assert.AreEqual(false, presenter.IsDangerousSQL("select 1"));
}

[Test]
public void User_Cant_Execute_Schema_SQL_On_Any_Environment()
{
    Assert.AreEqual(true, presenter.IsDangerousSQL("alter table"));
    Assert.AreEqual(true, presenter.IsDangerousSQL("DrOp table"));
}

//Updates, Deletes and Selects are allowed in Test, but not in Production
[Test]
public void User_Can_Only_Execute_Updates_Or_Deletes_Against_Test()
{
    //mockWindow.SetupSet(w => w.Environment = Environments.Test);
    mockWindow.Object.Environment = Environments.Test;
    Assert.AreEqual(false, presenter.IsDangerousSQL("update "));
    Assert.AreEqual(false, presenter.IsDangerousSQL("delete "));

    //mockWindow.SetupSet(w => w.Environment = Environments.Production);
    //mockWindow.Object.Environment = Environments.Test;
    Assert.AreEqual(true, presenter.IsDangerousSQL("update "));
    Assert.AreEqual(true, presenter.IsDangerousSQL("delete "));
}
私有模拟窗口;
对演示者演示者的私人查询;
/// 
///在运行任何测试之前运行一次
/// 
[TestFixtureSetUp]
public void TestFixtureSetUp()
{
//我们有兴趣在这里测试QueryFormPresenter类,但是我们
//不要真正关心QueryForm窗口(视图),因为其中几乎没有任何代码。
//因此,我们创建QueryForm视图的模拟,并将其传递给QueryFormPresenter以供使用。
mockWindow=newmock();
presenter=新的QueryFormPresenter(mockWindow.Object);
}
[测试]
public void User_Can_Execute_Selects_From_Any_Environment()
{
arenequal(false,presenter.isdangerussql(“选择1”);
}
[测试]
公共无效用户\u无法\u在\u任何\u环境()上执行\u架构\u SQL\u
{
AreEqual(true,presenter.isdangerussql(“altertable”);
AreEqual(true,presenter.isdangerussql(“DrOp table”);
}
//在测试中允许更新、删除和选择,但在生产中不允许
[测试]
公共无效用户\u只能\u根据\u测试()执行\u更新\u或\u删除\u
{
//mockWindow.SetupSet(w=>w.Environment=Environments.Test);
mockWindow.Object.Environment=Environments.Test;
arenequal(false,presenter.isdangerussql(“更新”);
Assert.AreEqual(false,presenter.isdangerussql(“delete”);
//mockWindow.SetupSet(w=>w.Environment=Environments.Production);
//mockWindow.Object.Environment=Environments.Test;
arenequal(true,presenter.isdangerussql(“更新”);
arenequal(true,presenter.isdangerussql(“delete”);
}
我非常感谢任何人能提供的见解!另外,
isdangerussql
方法是否应该实际位于模型类中,因为它表示业务逻辑,而不是直接对用户操作作出反应

谢谢


Andy

假设您的测试代码正在检查您希望使用SetupGet而不是SetupSet的环境属性(即,告诉模拟在调用其环境属性时返回什么)

这是因为您没有在获取的代码中设置属性

或者,如果希望将Environment属性视为标准属性,这就是您在编写以下语句时所做的

mockWindow.Object.Environment = Environments.Test;
你可以用

mockWindow.SetupProperty(qf => qf.Environment);

就我个人而言,我更喜欢第一种方法。

您能解释注释掉的代码吗?看起来你应该使用它。如果代码与“视图的表示”相关,它应该驻留在VM中-例如,你想突出显示坏sql。如果不是(例如,非视图客户端也需要),则应该深入到模型或实用程序类。非常感谢!!但是,如果我将mockWindow.Object.Environment=Environments.Test组合起来,第二种方法不起作用;使用mockWindow.SetupProperty(qf=>qf.Environment);。我同意第一种方法是可行的。谢谢
mockWindow.SetupProperty(qf => qf.Environment);