0

使用 FakeItEasy,如何断言发生了任何调用?

用例是我正在编写一个与存储库一起使用的类,并且作为一个方法的结果,该类应该通过调用 DeleteAll 或为所有元素调用 Delete 从存储库中删除一些元素。

现在,我使用了这样的 try-catch:

try // either
{
    A.CallTo(() => module.CardRepo.Delete(A<CardData>.That.IsEqualTo(dummy.CardData[0]))).MustHaveHappened();
    A.CallTo(() => module.CardRepo.Delete(A<CardData>.That.IsEqualTo(dummy.CardData[1]))).MustHaveHappened();
}
catch (ExpectationException) // or
{
    A.CallTo(() => module.CardRepo.DeleteAll(A<IEnumerable<CardData>>.That.Contains(dummy.CardData[0]))).MustHaveHappened();
    A.CallTo(() => module.CardRepo.DeleteAll(A<IEnumerable<CardData>>.That.Contains(dummy.CardData[1]))).MustHaveHappened();
}

但我不喜欢这样,如果有更多选择,它很快就会变得非常难看。有没有更好的办法?我在 FakeItEasy wiki 上找不到任何东西。

4

2 回答 2

2

这是一个示例,说明如何验证是否在假对象上调用了多个方法之一。

 public interface IBlah
{
    void Delete(int x);
    int Add(int x, int y);
    int Subtract(int x, int y);
}

public class Something
{
    private readonly IBlah _blah;

    public Something(IBlah blah) { _blah = blah; }

    public void DoSomething(int x, int y )
    {
      //  _blah.Add(x, y);
        _blah.Subtract(x, y);
    }
}

以上只是一个简单的系统来测试

   [Fact]
    public void TestFeature()
    {
        var fake = A.Fake<IBlah>();
        var something = new Something(fake);

        something.DoSomething(1, 2);

        var callResults = Fake.GetCalls(fake).Any(call =>
         {
             var x = call.GetArgument<int>("x");
             var y = call.GetArgument<int>("y");
             return call.Method.Name == "Add" || call.Method.Name == "Subtract"
                 && x == 1 && y == 2;
         });

        Assert.True(callResults);
    }

上面的直接代码片段是一个 XUnit 测试,它验证是否使用参数 x =1、y = 2 的给定值调用了 Add 或 Subtract

于 2013-02-08T21:48:18.360 回答
1

老实说,不确定您是否可以使用 FakeItEasy 做到这一点,您可能可以编写一个扩展方法来使您的代码看起来“更好”,尽管我同意这通常不是一个很好的解决方案。

我真正想说的是,通过单元测试你正在测试确定性行为,所以通过方法的输入你不应该知道是否应该调用 Delete 或 DeleteAll 吗?重点是不应该将这些分成不同的测试吗?也许我在这里没有关于你的案子的足够信息。

于 2012-12-11T12:28:17.117 回答