使用FakeItEasy的A.CallTo()传入非伪造对象抛出异常求助
First, let's get to the root of the error: FakeItEasy's A.CallTo() only works with fake objects that FakeItEasy itself creates. When you pass a real instance of your ABC class (myObject), FakeItEasy has no way to intercept or mock its method calls—hence the "not recognized as a fake object" exception.
The bigger issue here is that you can't create a fake of ABC in the first place. Let's cover the most common reasons for that and their fixes:
1. Your ABC class isn't fakeable by default
FakeItEasy can only fake types that meet one of these criteria:
- It's an interface
- It's an abstract class
- It's a concrete class with virtual methods (since FakeItEasy needs to override methods to mock them)
Fixes based on whether you can modify the ABC class:
Option A: You can modify ABC
- Extract an interface: Define an interface for the methods you need to mock, have
ABCimplement it, then fake the interface:public interface IABC { ResultType Add(DummyType dummyObject); } public class ABC : IABC { public ResultType Add(DummyType dummyObject) { // Real implementation } } // In your test: var fakeABC = A.Fake<IABC>(); A.CallTo(() => fakeABC.Add(A<DummyType>.Ignored)).Returns(result); - Make the
Addmethod virtual: If you don't want to use an interface, mark the method asvirtualso FakeItEasy can override it:public class ABC { public virtual ResultType Add(DummyType dummyObject) // Add 'virtual' { // Real implementation } } // In your test: var fakeABC = A.Fake<ABC>(); A.CallTo(() => fakeABC.Add(A<DummyType>.Ignored)).Returns(result);
Option B: You can't modify ABC (e.g., it's a third-party class)
Use the Wrapper Pattern to wrap the real ABC class in a fakeable interface:
- Create an interface that mirrors the methods you need from
ABC:public interface IABCWrapper { ResultType Add(DummyType dummyObject); } - Create a wrapper class that delegates to the real
ABCinstance:public class ABCWrapper : IABCWrapper { private readonly ABC _realABC; public ABCWrapper(ABC realABC) { _realABC = realABC; } public ResultType Add(DummyType dummyObject) { return _realABC.Add(dummyObject); } } - Now you can fake the
IABCWrapperinterface in your tests:var fakeWrapper = A.Fake<IABCWrapper>(); A.CallTo(() => fakeWrapper.Add(A<DummyType>.Ignored)).Returns(result); // If you ever need to use the real implementation, just instantiate the wrapper: var realWrapper = new ABCWrapper(new ABC());
2. Edge case: ABC is a sealed class
If ABC is marked sealed, FakeItEasy can't fake it directly (since sealed classes can't be inherited from). In this case, the Wrapper Pattern from Option B above is your best bet—you'll still wrap the sealed class in an interface and fake the interface instead.
Key Takeaway
Never try to use A.CallTo() on a real object—always use instances created with A.Fake<T>(). If you can't create a fake of T, adjust the type to be fakeable (via interface/virtual methods) or wrap it.
内容的提问来源于stack exchange,提问作者Gaurav Panwar

