-
-
Couldn't load subscription status.
- Fork 56
Description
In trying to use some SelfMocks for some things, I've ran into a couple different sharp edges.
1. There's no way to specify CallBase = true as a direct parameter to CreateSelfMock. Instead, I have to either configure the whole AutoMocker instance this way via its constructor, or I have to do the following:
var service = Mocker.CreateSelfMock<FooService>();
var mock = Mock.Get(service);
mock.CallBase = true;This pattern is just a little ugly - it'd be nice to have an additional bool parameter: CreateSelfMock<FooService>(usePrivate: false, callBase: true). Maybe also throw in an optional parameters for MockBehavior as well?
2. Registering self mocks that have an interface back into the Mocker is hard.
The following doesn't work, but intuitively feels like it should:
interface IFooService { int Foo() }
class FooService : IFooService {
public FooService(ISomeDependency dep1, IOtherDependency dep2) {}
virtual int Foo() => 42;
}
var service = Mocker.CreateSelfMock<FooService>();
Mocker.Use<IFooService>(service);
Mocker.Setup<IFooService, int>(s => s.Foo()).Returns(24);This throws with
Message:
System.ArgumentException : IFooService does not resolve to a Mock
Stack Trace:
AutoMocker.GetOrMakeMockFor(Type type)
AutoMocker.Setup[TReturn,TService](Func`2 returnValue)
AutoMocker.Setup[TService,TReturn](Expression`1 setup)
The same goes for using the concrete type without an interface - the following fails with the same exception.
var service = Mocker.CreateSelfMock<FooService>();
Mocker.Use<FooService>(service);
Mocker.Setup<FooService, int>(s => s.Foo()).Returns(24);Instead, to make this work, one has to do this:
// Via Interface
var service = Mocker.CreateSelfMock<FooService>();
Mocker.Use<IFooService>(Mock.Get(service).As<IFooService>());
Mocker.Setup<IFooService, int>(s => s.Foo()).Returns(24);
// Via concrete class:
var service = Mocker.CreateSelfMock<FooService>();
Mocker.Use<FooService>(Mock.Get(service));
Mocker.Setup<FooService, int>(s => s.Foo()).Returns(24);Would it be possible for Mocker.Use (the overloads that aren't already accepting a Mock<>) to automatically check if the provided object is a mock, and if so, register a MockInstance instead of a RealInstance? And likewise for interfaces, automatically performing the Mock.Get(x).As<T>() conversion?
Or would this cause horrible breaking changes? Another idea is a few new methods:
void UseSelfMock<T>(bool enablePrivate = false, bool? callBase = null) {
callBase ??= this.CallBase;
var obj = CreateSelfMock<T>(enablePrivate);
var mock = Mock.Get(obj);
Use(mock);
}
void UseSelfMock<T, TInterface>(bool enablePrivate = false, bool? callBase = null) {
UseSelfMock<T>(enablePrivate, callBase);
Combine<T, TInterface>();
}