-2

Given the following class, how can I test that when MethodUnderTest is called, GetSomething is invoked?

public class SystemUnderTest
{
    private Foo foo;

    public string MethodUnderTest(int input)
    {
       return foo.Get(x => x.GetSomething(input));
    }
}

Test

public void VerifyGetSomethingInvokedWhenMethodUnderTestIsInvoked()
{
   //Arrange
   var sut = new SystemUnderTest();
  
   //Act
   string unusedResult = sut.MethodUnderTest(5);

   //Assert
   A.CallTo(()=> sut.MethodUnderTest(A<int>.Ignored))  //Cant figure out how to test the Func<T> invocation           
   
}
Marshal
  • 6,551
  • 13
  • 55
  • 91

1 Answers1

3

In general, the approach to testing with fakes is

  1. create a fake object to abstract away your system under test's collaborator
  2. optionally configure the fake's behaviour
  3. create the system under test and provide the fake
  4. exercise the system under test
  5. optionally interrogate the fake

You're missing part 1, part of 3 (the "providing" part), and part 5 is slightly off. I don't know what x represents in your code, but you'd need to fake whatever type it is, and ensure that the fake is provided to the foo instance. Then you'd have something like

public void VerifyGetSomethingInvokedWhenMethodUnderTestIsInvoked()
{
   //Arrange
   var fakeX = A.Fake<IX>();
   var sut = new SystemUnderTest(fakeX); // maybe? which would pass it to `foo`?
  
   //Act
   string unusedResult = sut.MethodUnderTest(5);

   //Assert
   A.CallTo(() => fakeX.GetSomething(5)).MustHaveHappened();
}
Blair Conrad
  • 233,004
  • 25
  • 132
  • 111
  • 1
    Thank you. Sometimes you just need validation that what you were thinking looks long stretched, but it is the way to go. With a lot of generics and delegates involved in the actual code, it was hard to produce a sample code. You got the gist from my sample code, I appreciate all the info. Finally I got it working. :) – Marshal May 28 '21 at 12:10