验证方法是否正在单元测试中的另一个方法中调用

时间:2014-03-13 11:00:37

标签: c# unit-testing mvvm moq

我是单元测试视图模型,我正在使用带有moq的mbunit来模拟类的私有方法,但我的要求是在测试的断言部分验证是否调用了另一个方法(这是一个对话框)出现在单元测试的方法内。

2 个答案:

答案 0 :(得分:2)

您可以使用以下代码轻松检查使用Moq调用的方法:

[TestFixture]
public class UnitTest1
{
    [Test]
    public void TestMethod1()
    {
        // Create a mock of your interface and make the methods verifiable.
        var mock = new Mock<ISomeDependency>();
        mock.Setup(m => m.DoSomething())
            .Verifiable();

        // Setup your class which you expect to be calling the verifiable method
        var classToTest = new SomeClass(mock.Object);
        classToTest.DoWork();

        // Verify the method is called
        mock.Verify(m => m.DoSomething());
    }
}



public class SomeClass
{
    private readonly ISomeDependency _someDependency;

    public SomeClass(ISomeDependency someDependency)
    {
        _someDependency = someDependency;
    }

    public void DoWork()
    {
        _someDependency.DoSomething();
    }
}

public interface ISomeDependency
{
    void DoSomething();
}

public class SomeDependency : ISomeDependency
{
    public void DoSomething()
    {

    }
}

基本上,您正在寻找的是Ur单元测试的Arrange部分中的Verifiable,以及Assert部分中的Verify。

答案 1 :(得分:0)

当某些东西难以进行单元测试时,这就是“代码味道”和“#34;你有设计问题。

在这种情况下,根本问题是您尝试在viewmodel中执行UI操作。那很糟糕。

我在做MVVM时采用的方法是在我的视图模型中引发一个事件,例如: ConfirmationRequired。然后在视图中,我将事件处理程序挂钩到事件。我视图中的事件处理程序负责实际显示消息框。

单元测试很简单。此示例位于MSTest中,但MBUnit或多或少等效。

[TestMethod]
public void User_Confirmation_Is_Requested()
{
    var mre = new ManualResetEvent(false);
    var vm = MyApplicationViewModel();
    ConfirmationRequestedEventArgs actual = null;
    vm.ConfirmationRequired += (sender, args) => {
    {
            actual = args;
            mre.Set();
    };

    vm.DoSomethingThatRequiresConfirmation();
    if (!mre.WaitOne(1000))
    {
        Assert.Fail("The event was never received.");
    }
    Assert.AreEqual("Whatever", actual.SomeProperty ?? string.Empty);
}

这里最棒的是你甚至可以模拟用户的回复 - 让我们说你的ConfirmationRequestedEventArgs有一个名为UserResponse的属性。您可以在单元测试的事件处理程序中设置UserResponse,然后确保当用户单击&#34;取消&#34;按钮,viewmodel中的其他一些状态也会相应更改。