Search code examples
.netunit-testingc#-4.0microsoft-fakes

Why does Fakes execute real method?


I've stubbed a class using MS Fakes. This class is injected into another class that is not stubbed:

var stubClassA = new MyNamespace.Fakes.StubClassA();
ClassB classB = new ClassB(stubClassA);
classB.DoSomething(10);

When I step into classB.DoSomething(), the classA instance is there and I can see it is correctly stubbed.

In classB.DoSomething(int empId)

classA.GetEmployee(empId);

The above does a real call to classA.GetEmployee(). Shouldn't that just return null and not try to execute the real code?

I did try to stub GetEmployee():

stubClassA.GetEmployee = (value) => new Employee();

but it throws the compile time error:

Cannot assign to 'GetEmployee' because it is a 'method group'

Signature of GetEmployee in ClassA

public Employee GetEmployee(int empId)

Any ideas what I'm doing wrong?


Solution

  • You need to ensure that your ClassA implements an interface, so that MS Fakes can implement a stub for it.

    A small example that I threw together:

    namespace TestLib
    {
        public class Employee
        {
            public int Id;
        }
    
        public interface IClassA
        {
            Employee GetEmployee(int empId);
        }
        public class ClassA : IClassA
        {
            public Employee GetEmployee(int empId)
            {
                return new Employee(){Id = empId};
            }
        }
    
        public class ClassB
        {
            private IClassA _classA;
    
            public ClassB(IClassA a)
            {
                this._classA = a;
            }
    
            public void DoSomething(int id)
            {
                _classA.GetEmployee(id);
            }
        }
    }
    

    Now you can stub out ClassA like so:

    var b = new StubIClassA()
    {
        GetEmployeeInt32 = (val) => new StubEmployee()
    };