0

I have the following scenario:

public class Child : Parent
{

private int _eventTypeId;
 public override Dictionary<string, dynamic> Execute(IDynamicDatabaseConnection dbConn, IDbTransaction dbTrans)
        {
_eventTypeId = GetEventType(dbConn, dbTrans);
}
}
public abstract class Parent : ParentInterface
    {
protected int GetEventType(IDynamicDatabaseConnection dbConn, IDbTransaction dbTrans) => GetItemId("EventType", "User Initiated", dbConn, dbTrans);

 protected int GetItemId(string param1, string param2, IDynamicDatabaseConnection dbConn, IDbTransaction dbTrans) =>
            dbConn.Query<int>(
                $@"myQuery",
                dbTrans).FirstOrDefault();


public abstract Dictionary<string, dynamic> Execute(IDynamicDatabaseConnection dbConn, IDbTransaction dbTrans);
}
    public interface ParentInterface
    {
        Dictionary<string, dynamic> Execute(IDynamicDatabaseConnection dbConn, IDbTransaction dbTrans);
    }

How should I be mocking the GetEventType method from my child class?

I use mocking in the following way.

            var connMock = A.Fake<IDynamicDatabaseConnection>();
            var transMock = A.Fake<IDbTransaction>();
            A.CallTo(() => connMock.BeginTransaction()).Returns(transMock);
A.CallTo(() => dbConnMock.Query<string>(null, null, null, A<bool>._, null, null)).WithAnyArguments().Returns(new List<string>() { "AfterSaveSPName" });

Update: Adding the Child Class Test Method which I am testing.

        [TestMethod]
        public void Initiate_Intake_Should_Insert_FormMode_Initiate()
        {
            // Arrange
            Dictionary<string, dynamic> childParameters = new Dictionary<string, dynamic>
            {
                 {Key, -1}
            };
            var dynamicAssembly = A.Fake<IDynamicAssembly>();
            var connMock = A.Fake<IDynamicDatabaseConnection>();
            var transMock = A.Fake<IDbTransaction>();
            var fakeInitiateIntake = A.Fake<InitiateBase>(options => options.Implements<IInitiateBase>());
            
A.CallTo(() => connMock.BeginTransaction()).Returns(transMock);
            A.CallTo(fakeInitiateIntake).Where(call => call.Method.Name == "GetEventType")
                .WithReturnType<int>()
                .Returns(197);

            // Act
            var child = new Child(childParameters, dynamicAssembly);
            child.Execute(connMock, transMock);

            // Assert
            initiateParameters["Key"].Equals(1234);
        }
tRuEsAtM
  • 3,517
  • 6
  • 43
  • 83
  • You could create a [TestClass] like => ChildTestClass : Parent ... inside your test. https://stackoverflow.com/questions/13416223/unit-testing-c-sharp-protected-methods – Mate May 17 '22 at 23:18
  • "I use mocking in the following way." Ok, but what happens when you tried that approach? Did you get an error? – Kirk Woll May 17 '22 at 23:31
  • @KirkWoll Yes, It didn't mock `GetEventType` the way I hoped. – tRuEsAtM May 17 '22 at 23:33
  • @Mate But, the comments on the accepted answer tell that it's not the right way. I am hoping to find the right way to mock this. – tRuEsAtM May 17 '22 at 23:34
  • You didn't specify `GetEventType` at all in your mocking code. Can you elaborate a bit more? – Kirk Woll May 17 '22 at 23:34
  • @KirkWoll Yeah, how should I do that is the main question. That method is protected in the Parent class. – tRuEsAtM May 17 '22 at 23:35
  • Right, but if the problem is simply that you can't access it if it's protected, it would really help for you to show the code which _tried_ to reference the protected method (even if it won't compile), and then we could (hopefully) come up with solutions that addressed that. – Kirk Woll May 17 '22 at 23:39
  • @tRuEsAtM Think it as a stub. Maybe that comments apply to another scenario. How do the test / fwk tools work under the hood? – Mate May 17 '22 at 23:54
  • https://stackoverflow.com/questions/5601730/should-private-protected-methods-be-under-unit-test – Mate May 18 '22 at 00:03
  • This cannot be done with constrained isolating frameworks such as Moq, NSubstitute, FakeItEasy. This is possible with the help of unconstrained frameworks such as TypeMock, JustMock, MS Fakes, Prig, Ionad.Fody, Pose, Harmony, MethodRedirect – Alexander Petrov May 18 '22 at 15:00
  • 1
    @Mate I have updated the question with the method I am trying to test. – tRuEsAtM May 18 '22 at 17:20
  • @KirkWoll I have updated the question with the method I am trying to test. – tRuEsAtM May 18 '22 at 17:20

1 Answers1

0

You haven't said, but I'm assuming you're trying to test Child.

First, note that FakeItEasy will not be able to intercept calls to GetEventType unless the method is virtual or abstract. If you're able to make that change, you can follow the instructions at Specifying a call to any method or property, which shows an example using a protected method's name to identify it. You'll end up with something like this:

A.CallTo(fakeChild).Where(call => call.Method.Name == "GetEventType")
                   .WithReturnType<int>()
                   .Returns(197);
Blair Conrad
  • 233,004
  • 25
  • 132
  • 111
  • What is `fakeChild`? Is it an object of Child class? You are right I want to test the Child class. – tRuEsAtM May 18 '22 at 16:20
  • I have updated the question with the method I am trying to test. – tRuEsAtM May 18 '22 at 17:20
  • `fakeChild` was to have been a fake `Child`. You said you wanted to mock "the `GetEventType` method from [the] child class", so it sounded like you needed a fake Child. If that's true, I think you make a fake Child and use something like my answer. With your update, I don't know really how to help you. We don't know what `InitiateBase` is, nor how it's connected to `Child`. You fake it, but then never supply `fakeInitiateIntake` to `Child`. And then `initiateParameters` shows up at the end, unconnected to anything. – Blair Conrad May 19 '22 at 10:37