0

I am new to writing unit test cases using Fake It Easy. I could not able to figure it out that, How can we validate that method is called by some specific parameters?

Please see the example below

Main Class

//Model
public class Request 
{
    public string Param { get; set; }
}

//Repository
public class MyRepository : IMyReporitory
{
    public string Get(Expression<Func<Request, bool>> query) { }
}

//Service
public class MyService
{
    private readonly IMyReporitory _myReposotory;
    public MyService(IMyReporitory myReposotory) 
    {
        _myReposotory = myReposotory;
    }

    public string Search(string searchText) 
    {
       return _myReposotory.Get(x => x.Param == searchText);  
    }
}

Test Class

[TestClass]
public class DashboardServiceTest
{
    MyService service;
    IMyRepository _fakeMyRepository;

    public void Initialize()
    {
        _fakeMyRepository= A.Fake<IMyRepository>();
        service = new MyService(_fakeMyRepository);
    }

    [TestMethod]
    public void GetFilteredRfqs_FilterBy_RfqId()
    {
       var result = service.Search("abc");
       A.CallTo(() => _fakeMyRepository.Get(A<Expression<Func<Request, bool>>>._)).MustHaveHappened();
    }
}

In this example how can I check that _myReposotory.Get() method is called with "abc" parameter?

rajk
  • 221
  • 3
  • 19
  • 1
    It sounds like the real problem is difficulty in determining whether the predicate passed in was the right one. Does this answer your question? [How to test for a Match with FakeItEasy on a predicate call?](https://stackoverflow.com/questions/21437044/how-to-test-for-a-match-with-fakeiteasy-on-a-predicate-call) – Blair Conrad Apr 06 '20 at 10:42

1 Answers1

0

do this!

[TestMethod]
public void GetFilteredRfqs_FilterBy_RfqId()
{
   //the test that get was called with the x => x.Param == "abc" parameter
   A.CallTo(() => _fakeMyRepository.Get(x => x.Param == "abc")).MustHaveHappened();

   //or this (you can add any any specific test replace "default")
   A.CallTo(() => _fakeMyRepository.Get(x => x.Param == "abc")).WhenArgumentsMatch(default);

   //or this
   A.CallTo(() => _fakeMyRepository.Get(x => x.Param == "abc")).WhenArgumentsMatch((Expression<Func<Request, bool>> query) => true).Returns("Correctly worked!!");

   //this throws an exception if query.ReturnType.Name == "xyz"
   A.CallTo(() => _fakeMyRepository.Get(x => x.Param == "abc")).WhenArgumentsMatch((Expression <Func<Request, bool>> query) => query.ReturnType.Name == "xyz" /*query.Equals(default)*/).Throws<Exception>();

  //I EDITED THIS POST TO ADD THIS ONE

  //if you want to make more detail check on your parameter, you can do this!
  A.CallTo(() => _fakeMyRepository.Get(A<Expression<Func<Request, bool>>>.That.Matches(s => s.Type.Name == "xyz"))).MustHaveHappened();
}
  • No, In unit test how can check that _fakeMyRepository.Get(A>>._)) is called with "x => x.Param == abc" as a parameter. – rajk Apr 06 '20 at 00:50
  • you passed the value, so you know what it was called with (what else?!)... A.CallTo(() => _fakeMyRepository.Get(x => x.Param == "abc")).MustHaveHappened();... – Oluwadamilola Adegunwa Apr 06 '20 at 01:29
  • No, that won't work. Parameters are compared by reference, and the lambda in your test won't be the same instance as the one passed by the production code. – Thomas Levesque Apr 06 '20 at 08:15
  • @ThomasLevesque, I added one one to the post. this one makes you flexible about what you want to test in the parameter!! I hope it helps! – Oluwadamilola Adegunwa Apr 06 '20 at 10:40
  • @Damilola your last one doesn't even make sense... The `s` in the lambda is an `Expression>`, so `s.Type.Name` is the name of the `Expression>` type (in fact, it's the short name, `Func\`2`) – Thomas Levesque Apr 06 '20 at 12:09
  • No @ThomasLevesque! I'm just showing that you can do any kind of check on the input. say it is an int, you can make sure it is equal to 10, or if string, you can check if it has some character... that was just lack of better example, sorry!!!, sorry again!, I wish i had a better example! – Oluwadamilola Adegunwa Apr 06 '20 at 13:47
  • Yes, but that doesn't check that the parameter is the expected lambda, so it doesn't solve the OP's problem... But no need to be sorry, at least you're trying to help ;) – Thomas Levesque Apr 07 '20 at 10:09