0

With FakeItEasy, how to assert, that any of calls has happened?

The use case is I'm writing a class that works with a repository and as a result of a method, the class should remove some elements from the repository, either by calling DeleteAll, or by calling Delete for all of them.

For now, I've used a try-catch like this:

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();
}

but I don't like that and for more choices it would quickly become really ugly. Is there a better way? I couldn't find anything on FakeItEasy wiki.

voidengine
  • 2,504
  • 1
  • 17
  • 29

2 Answers2

2

Here's an example of how you can verify if one of more methods were called on a fake object.

 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);
    }
}

Above is just a trivial system to test

   [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);
    }

Above immediate snippet above is a XUnit test that verifies if either Add or Subtract were called with the giving values for the parameters x =1, y = 2

cecilphillip
  • 11,446
  • 4
  • 36
  • 40
1

Not sure if you can do this with FakeItEasy to be honest, you could probably write an extension method to make your code look 'nicer', although I agree it's not a great solution in general.

What I really wanted to say was that through unit teesting you're testing deterministic behavior, so through the input to the method shouldn't you know whether a call to Delete or DeleteAll should be made? The point being shouldn't these be split out into different tests? Maybe I don't have enough info about your case here.

user303754
  • 459
  • 3
  • 11
  • 2
    +1 The comments made here seem right to me. The method under test should behave deterministically given a known set of inputs. I'm trying to imagine why you might be in this situation. Perhaps the test is more of a functional test where the input comes from a real database that's in an unpredicatable starting state. Why wouldn't you know which methods are going to be called? Perhaps the same test is being used for more than one class. Either way, it seems like a more focussed unit test is needed, that only tests a single method and creates a context with known starting conditions. – Tim Long Dec 27 '12 at 14:06