模拟方法以返回某些参数并为所有其他参数抛出异常

A-S*_*ani 3 c# moq

Moq用来模拟一个方法:

public class DbService : IDbService
{
    public Record GetRecord(Guid Id)
    {
        // Returns the record if exists.
        // Throws exception if record not found.
    }
}
Run Code Online (Sandbox Code Playgroud)

我想模拟一下,如果我传递这三个 guid,它会返回记录,并且所有其他 Guid 都会抛出异常。

Guid id = Guid.NewGuid();
Guid id2 = Guid.NewGuid();
Guid id3 = Guid.NwGuid();

var mock = new Mock<IDbService>();
mock.Setup(t => t.GetRecord(id)).Returns(record1);
mock.Setup(t => t.GetRecord(id2)).Returns(record2);
mock.Setup(t => t.GetRecord(id3)).Returns(record3);
// Throw exception for all other guids...
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?

A-S*_*ani 6

其实这很简单:

mock.Setup(t => t.GetRecord(It.IsAny<Guid>())).Throws(new MyException());
mock.Setup(t => t.GetRecord(id)).Returns(record1);
mock.Setup(t => t.GetRecord(id2)).Returns(record2);
mock.Setup(t => t.GetRecord(id3)).Returns(record3);
Run Code Online (Sandbox Code Playgroud)

  • 这很好,但请注意,对于某些值(三个特定的 GUID),您有两个匹配的“Setup”,在这种情况下,“Setup”调用的顺序就变得很重要。这就是为什么您将 `It.IsAny&lt;Guid&gt;()` 行放在前面,而不是最后。如果您不想依赖于“Setup”的顺序,请选择 Maor Veitsman 的解决方案(其他答案)。如果您愿意,也可以写成`.Setup(t =&gt; t.GetRecord(It.Is((Guid q) =&gt; q != id &amp;&amp; q != id2 &amp;&amp; q != id3)))`。如果列表(或集合)中有很多,`.Setup(t =&gt; t.GetRecord(It.Is((Guid q) =&gt; !yourList.Contains(q))))`。 (2认同)

tak*_*gen 5

您可以MockBehavior.Strict为此使用:

Guid id = Guid.NewGuid();
Guid id2 = Guid.NewGuid();
Guid id3 = Guid.NwGuid();

var mock = new Mock<IDbService>(MockBehavior.Strict);

mock.Setup(t => t.GetRecord(id)).Returns(record1);
mock.Setup(t => t.GetRecord(id2)).Returns(record2);
mock.Setup(t => t.GetRecord(id3)).Returns(record3);

// do stuff

// will throw if GetRecord was called with arguments
// that don't match to any configured setup.
mock.VerifyAll();
Run Code Online (Sandbox Code Playgroud)