使用 Moq 与 Rhino Mock 进行 Try Catch 测试

发布于 2024-08-23 17:49:36 字数 745 浏览 2 评论 0 原文

我刚刚使用 Moq 进行了一些测试,但在尝试测试我想通过 try catch 块调用两次的方法时遇到了麻烦。原理是第一次调用抛出异常,然后在catch中纠正问题并再次调用该方法。

我成功地使用 Rhino Mocks 做到了这一点,如下所示,但对于这两个框架都是新手,我想知道是否有人可以告诉我是否可以使用 Moq 来实现相同的目标。

// C.U.T
public class Mockee
{
    bool theCatLives = true;

    public Mockee() { }

    public virtual void SetFalse()
    {
        theCatLives = false;
    }
}


[Test]
public void TestTryCatch(){

    var mr = new MockRepository();
    var mock = mr.StrictMock<Mockee>();
    mr.Record();
    Expect.Call(mock.SetFalse).Throw(new Exception());
    Expect.Call(mock.SetFalse);
    mr.ReplayAll();

    try
    {
        mock.SetFalse();
    }
    catch
    {
        mock.SetFalse();
    }

    mock.VerifyAllExpectations();
}

I've just been working on some tests using Moq but ran into trouble trying to test a method I wanted to call twice through a try catch block. The principle is that the first call throws an exception, then in the catch I correct the problem and call the method again.

I managed to do it with Rhino Mocks as below but being new to both frameworks I wondered if anyone could tell me if the same can be achieved using Moq.

// C.U.T
public class Mockee
{
    bool theCatLives = true;

    public Mockee() { }

    public virtual void SetFalse()
    {
        theCatLives = false;
    }
}


[Test]
public void TestTryCatch(){

    var mr = new MockRepository();
    var mock = mr.StrictMock<Mockee>();
    mr.Record();
    Expect.Call(mock.SetFalse).Throw(new Exception());
    Expect.Call(mock.SetFalse);
    mr.ReplayAll();

    try
    {
        mock.SetFalse();
    }
    catch
    {
        mock.SetFalse();
    }

    mock.VerifyAllExpectations();
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

居里长安 2024-08-30 17:49:36

这对于起订量来说并不是特别容易,因为它没有有序期望的概念。但是,您可以使用 Callback 方法并从那里引发异常,如下所示:

var actions = new Queue<Action>(new Action[] 
{
    () => { throw new Exception(); },
    () => { } 
});

var mock = new Mock<Mockee>();
mock.Setup(m => m.SetFalse()).Callback(() => actions.Dequeue()()).Verifiable();

try
{
    mock.Object.SetFalse();
}
catch
{
    mock.Object.SetFalse();
}
mock.Verify();

但是,需要注意的是,此版本仅检查是否调用了 SetFalse 方法。

如果您想验证它是否被调用了两次,您可以将最后一个语句更改为:

mock.Verify(m => m.SetFalse(), Times.Exactly(2));

但是,这稍微违反了 DRY 原则,因为您将两次声明相同的设置,但是您可以通过首先声明并定义一个来解决这个问题Expression> 类型的变量并将其用于 SetupVerify 方法...

This isn't particularly easy to do with Moq, as it has no concept of ordered expectations. You can, however, use the Callback method and throw exceptions from there, like this:

var actions = new Queue<Action>(new Action[] 
{
    () => { throw new Exception(); },
    () => { } 
});

var mock = new Mock<Mockee>();
mock.Setup(m => m.SetFalse()).Callback(() => actions.Dequeue()()).Verifiable();

try
{
    mock.Object.SetFalse();
}
catch
{
    mock.Object.SetFalse();
}
mock.Verify();

However, one caveat is that this version only checks whether the SetFalse method was called at all.

If you want to verify that it was called twice, you can change the last statement to this:

mock.Verify(m => m.SetFalse(), Times.Exactly(2));

However, this slightly violates the DRY principle because you would be stating the same Setup twice, but you could get around that by first declaring and defining a variable of type Expression<Action<Mockee>> and use it for both the Setup and the Verify methods...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文