I'm trying to proxy calls to a fake object to the actual implementation. The reason for this is that I want to be able to use the WasToldTo and WhenToldTo of Machine.Specifications which only works on fakes of an interface type.
Therefore I'm doing the following to proxy all calls to my real object.
public static TFake Proxy<TFake, TInstance>(TFake fake, TInstance instance) where TInstance : TFake
{
fake.Configure().AnyCall().Invokes(x => x.Method.Invoke(instance, x.Arguments.ToArray()));
return fake;
}
I would use that like this.
var fake = Proxy<ISomeInterface, SomeImplementation>(A.Fake<ISomeInterface>(), new SomeImplementation());
//in my assertions using Machine.Specifications (reason I need a fake of an interface)
fake.WasToldTo(x => x.DoOperation());
The problem however is that this only works for void methods, since the Invokes method is not doing anything with the return value. (Action param instead of Func)
Then I was trying to do this using the WithReturnValue method.
public static TFake Proxy(TFake fake, TInstance instance) where TInstance : TFake
{
fake.Configure().AnyCall()..WithReturnType().Invokes(x => x.Method.Invoke(instance, x.Arguments.ToArray()));
fake.Configure().AnyCall()..WithReturnType().Invokes(x => x.Method.Invoke(instance, x.Arguments.ToArray()));
fake.Configure().AnyCall()..WithReturnType().Invokes(x => x.Method.Invoke(instance, x.Arguments.ToArray()));
//etc.
return fake;
}
However the Invokes method still doesn't work the way I want it (still Action instead of Func). So The return value is still not used.
Is there a way of achieving this with the current latest version?
I already filed an issue at the FakeItEasy github repository. https://github.com/FakeItEasy/FakeItEasy/issues/435
Stealing from my response at the FakeItEasy github repository:
You can create a fake to wrap an existing object like so:
var wrapped = new FooClass("foo", "bar");
var foo = A.Fake<IFoo>(x => x.Wrapping(wrapped));
(example taken from Creating Fakes > Explicit Creation Options)
That should delegate all calls to the underlying object, with the usual caveat that any redirected calls have to be overrideable.
I hope this helps. If not, come back and explain again. Maybe I'll understand it better.
Oh, and beware the Configure mechanism. It's going away in FakeItEasy 2.0.0.
The preferred idiom is
A.CallTo(fake).Invokes(…); // or
A.CallTo(fake).WithReturnType<bool>(…);
Related
I am working on a discord bot project written in c# and currently trying to implement unit tests for the system using NUnit and Moq. For one of the features I need to access the server roles, which is done by
client.Guilds.First().Roles.Where(r => r.Name.Equals(roleName)).FirstOrDefault(); (ListManager.ModifyPermission, Line 116 ListManager.cs).
The client object is a instance of DiscordSocketClient from the Discord.Net library and is passed into the constructor of the class, the roles are accessed in, via dependency injection. So specifically I need client.Guilds.First().Roles to return a Collection filled with two mocked roles in it. My Problem however is, that Moq doesn't support mocking of non-virtual classes like SocketRole, or SocketGuild (container for a guild object). They each implement a corresponding interface (IRole, IGuild), however it is not possible to convert from the Interface to its related class.
The entire code can be accessed here. Affected is the ListManager class. ListManagerTestsHelper.GetDiscordSocketClient is where the mocking of the client should happen. I already thought about passing a list of the existing roles directly into the ListManager class, however the dependency injection is set up before the DiscordSocketClient connects, therefore there are no roles assigned to it at the point in time of setup.
Edit:
Generally I only need to know, if there is a way to return a Collection<Interface> from a mocked object, even though the actual object should return Collection<ObjectThatImplementsInterface>, because the Interface contains all the data that is needed for the test and the actual method that uses it.
Maybe you can change the field:
private readonly DiscordSocketClient client;
in the ListManager into just the guilds, that is:
private readonly IReadOnlyCollection<IGuild> guilds;
and then of course change its constructor accordingly.
Then you do just:
guilds.First().Roles.Where(r => r.Name.Equals(roleName)).FirstOrDefault()
or equivalently:
guilds.First().Roles.FirstOrDefault(r => r.Name == roleName)
I think you should be able to pass in client.Guilds when you construct the ListManager from your "real" code. That is because of nice covariance of the IReadOnlyCollection<out T> type.
In your test, you can just pass a new[] { guildMoq1.Object, guildMoq2.Object, } where guildMoq1 etc. is a Mock<IGuild> where you have setup the .Roles as desired (again you should be able to use just a new [] { ... } for setting up .Roles).
Edit:
Maybe in the ListManager use a Func<>:
private readonly Func<IReadOnlyCollection<IGuild>> getGuilds;
and the same Func<> in the signature of the constructor. Then that constructor argument can be given as:
() => client.Guilds
from your "real code". In this way you can construct your ListManager already at a time when client.Guilds is not ready to be asked yet. The client reference will be "captured" in the Func<> (closure semantics).
In the test, you can use:
() => new[] { guildMoq1.Object, guildMoq2.Object, }
where guildMoq1 etc. are as before?
Of course the line in ListManager will now look like this:
getGuilds().First().Roles.FirstOrDefault(r => r.Name == roleName)
Disclaimer - this is not the same question as How to use FakeItEasy to assert a method was not called
Explanation
I have a piece of code which registers stuff with an IOC container, and I can use FakeItEasy in my tests to ensure that registrations are made.
I am trying to work out how to ensure that unexpected calls are not made.
Quick repo (problem boiled down to a couple of test classes - this is not a real implementation)
public class Foo
{
private readonly ICustomContainer m_CustomContainer;
public Foo(ICustomContainer customContainer)
{
m_CustomContainer = customContainer;
}
public void Bar()
{
m_CustomContainer.Register<IMyInterface, IMyImplementation>();
}
}
public interface ICustomContainer
{
void Register<TInterface, TImplementation>() where TImplementation : TInterface;
}
public class UnitTest1
{
[Fact]
public void Test1()
{
//Arrange
ICustomContainer fake = A.Fake<ICustomContainer>();
Foo objectUnderTest = new Foo(fake);
//Act
objectUnderTest.Bar();
//Assert
A.CallTo(() => fake.Register<IMyInterface, IMyImplementation>()).MustHaveHappened();
//A.CallTo(() => fake.Register<???>()).MustNotHaveHappened(); //Any generic parameter apart from <IMyInterface, IMyImplementation> must not have happened
}
}
The above test will pass - which is correct. If in the future I was to add another registration in the Bar(), it would still pass - which isn't so good as my test is only testing known scenarios.
What I am trying to achieve
So, given the interface defined above for ICustomContainer which is my IOC container, I would like to ensure that it is called only as expected.
What I have already investigated
Having used other mocking frameworks in the past such as TypeMock Isolator, I could set the fake object up to throw exceptions unless specific (expected) calls are made. I don't know if I can do this with FakeItEasy. Also TypeMock Isolator doesn't support .NET Core, so it is no good to me.
If I had a method that didn't use a generic parameter, I could get FakeItEasy to count the number of times that the method had been invoked, and expect that it had been invoked with any arguments in addition to testing the expected calls. That is certainly an option, but means that I have to create a facade over my interface (as an extension method or a wrapper, I guess) to take in type parameters rather than generic parameters, which means that I lose the pre-compile time warnings I get with the generic parameter constraint.
The actual question
How do I amend my test so that I can assert that an unexpected call was not made with any generic parameters other than those I was expecting using .NET Core / FakeItEasy / xUnit?
I may be oversimplifying, but it sounds like a Strict Fake can help you.
Make one, then explicitly allow whatever calls you want.
//Arrange
ICustomContainer fake = A.Fake<ICustomContainer>(x => x.Strict());
// allow just the registrations you want to
A.CallTo(() => fake.Register<IMyInterface, IMyImplementation>()).DoesNothing();
Foo objectUnderTest = new Foo(fake);
//Act
objectUnderTest.Bar();
//Assert
A.CallTo(() => fake.Register<IMyInterface, IMyImplementation>()).MustHaveHappened();
I have an api service that calls another api service. When I set up the Mock objects, it failed with an error:
NotSupportedException: expression references a method that does not belong to the mocked object.
This is the code:
private Mock<IEnumerable<ICarrierApiService<AccountSearchModel>>> _mockCarrierService;
private Mock<IApiService<AccountSearchModel>> _mockApiService;
[SetUp]
public void SetUp()
{
_mockApiService = new Mock<IApiService<AccountSearchModel>>();
_mockCarrierService = new Mock<IEnumerable<ICarrierApiService<AccountSearchModel>>>();
_mockApiService.Setup(x => x.GetFromApiWithQuery(It.IsAny<string>())).Returns(ApiValue());
// Error occurred when call _mockApiService.GetFromApiWithQuery() in .Select()
_mockCarrierService.Setup(x => x
.Select(s => s
.GetFromApiWithQuery(It.IsAny<string>())).ToList())
.Returns(new List<IQueryable<AccountSearchModel>> { ApiValue() });
}
I read Expression testing with Moq but it didn't work for my case. If I remove this _mockCarrierService.Setup(), the test case can run but fails with a NullReferenceException because it didn't have a valid List<IQueryable<AccountSearchModel>> set up.
Any idea how I can achieve this?
Footnote: Current Solution
FWIW, here's the solution that I currently use. I am all ears for a better approach to the issue (until Moq starts supporting mocking extension methods).
private List<ICarrierApiService<AccountSearchModel>> _mockCarrierService;
private AccountSearchController _mockController;
private Mock<ICarrierApiService<AccountSearchModel>> _mockApiService;
[SetUp]
public void SetUp()
{
_mockApiService = new Mock<ICarrierApiService<AccountSearchModel>>();
_carrierServiceMocks = new List<ICarrierApiService<AccountSearchModel>> { _mockApiService.Object };
_mockApiService.Setup(x => x.GetFromApiWithQuery(It.IsAny<string>())).Returns(ApiValue());
_mockController = new AccountSearchController(_carrierServiceMocks);
}
Footnote: alternative mocking framework
I've also found a commercial mocking framework that supports mocking extension method and link to the how-to docs: Telerik JustMock.
This problem occurs because you are trying to mock Select method, which is an extension method, not an instance method of IEnumerable<T>.
Basically, there is no way to mock an extension method. Have a look at this question for some ideas that you may find useful.
UPD (12/11/2014):
To gain more understanding on mocking extension methods, think about the following:
Although extension methods are called as if they were instance methods on the extended type, they are actually just a static methods with a bit of syntactic sugar.
Extension methods from System.Linq namespace are implemented as pure functions — they are deterministic and they don't have any observable side effects. I agree that static methods are evil, except those that are pure functions — hope you would agree with this statement too :)
So, given an object of type T, how would you implement static pure function f(T obj)? It is only possible by combining other pure functions that are defined for object T (or any other pure functions, actually), or by reading immutable and deterministic global state (to keep function f deterministic and side-effect-free). Actually, "immutable and deterministic global state" has more convenient name — a constant.
So, it turns out that if you follow the rule that static methods should be pure functions (and it looks like Microsoft follows this rule, at least for the LINQ methods), mocking an extension method f(this T obj) should be reducible to mocking non-static methods or state used by that extension method — simply because that extension method relies on the obj instance methods and state in its implementation (and possibly on the other pure functions and/or constant values).
In case of IEnumerable<T>, Select() extension method is implemented in terms of foreach statement which, in turn, uses GetEnumerator() method. So you can mock GetEnumerator() and achieve required behavior for extension methods that rely on it.
You have:
_mockCarrierService = new Mock<IEnumerable<ICarrierApiService<AccountSearchModel>>>();
So you mock IEnumerable<>. The only member IEnumerable<> has is a method GetEnumerator() (plus another method with the same signature GetEnumerator() inherited from the base interface). The Select method is really an extension method (as was pointed out in the first answer) which is a static method that works by calling GetEnumerator() (possibly through C# foreach statement).
It is possible to make things work by doing Setup of GetEnumerator on your mock.
However, it is much simpler to simply use a concrete, non-mock type which "is" IEnumerable<>, such as List<>. So try:
_mockCarrierService = new List<ICarrierApiService<AccountSearchModel>>();
Then add an entry to the List<>. What you should add, is a Mock<ICarrierApiService<AccountSearchModel>> on which GetFromApiWithQuery Method is setup.
also if u need to Mock IConfiguration u can use this code below:
var builder = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string, string>
{
{ "your-key", "your value" }
});
var config = builder.Build();
Since the question about mocking IConfiguration is referring this answer as duplicate, I will contribute my dime here.
This is how I "Mock" IConfiguration, which is, in my opinion, a bit cleaner:
private static IConfiguration GetConfigurationMock(string jsonConfiguration)
{
var byteArray = Encoding.UTF8.GetBytes(jsonConfiguration);
var stream = new MemoryStream(byteArray);
var conf = new ConfigurationBuilder();
conf.AddJsonStream(stream);
var confRoor = conf.Build();
return confRoor;
}
Original question: How to setup Mock of IConfigurationRoot to return value
I have an interface with a number of generic methods. These methods perform operations based on the type of data that is passed in. How do I mock this with NSubstitute? At the moment, I had to resort to using a concrete class instead of a mock since I cannot handle all possible types that the method will be called with.
public interface IInstanceSource
{
bool CanCreate<T>();
T Create<T>();
void Register<T>(Func<T> creator);
}
public static IInstanceSource GetInstanceSource()
{
var _data = new Dictionary<Type, Func<object>>();
var a = Substitute.For<IInstanceSource>();
//code below fails since T is not defined. How do I make the code below accept any type?
a.WhenForAnyArgs(x=>x.Register(Arg.Any<Func<T>>)).Do(x=> { /* todo */});
a.CanCreate<T>().Returns(x => _data[typeof (T)]);
return a;
}
thanks.
NSubstitute doesn't support setting up multiple instances of a generic method automatically.
The way we'd normally see IInstanceSource used in a test is to configure it for a specific bit of code under test, so T would be known. If a single fixture needed to work for a few different Ts, we could make configuration simpler by having a helper method like ConfigureInstanceSource<T>() which would do the configurations steps for a specific T.
In your case though it seems like you want a fixed behaviour for all fake instances of IInstanceSource, in which case I believe you are going the right way about it by hand-coding your own test double.
I use RhinoMocks for a very simple test (I have to say I'm a beginner here). I tried to mock my object like this
var mock = MockRepository.GenerateMock<MyClass>();
create a helper stub :
var stubLinkedObject = MockRepository.GenerateStub<MyClass>();
then execute some logic which should call the method AddLink of the class MyClass with my stub argument. At the end of the test I simply assert that this method was actually called with
mockAction.AssertWasCalled(a => a.AddLink(stubLinkedObject));
I injected the correct dependency and the method is actually called. However, the problem is that the real implementation in MyClass is called and results in crash because some logic just can't be executed (link collection is not available etc.). How can I bypass the execution and simply check whether a method is called ? I have tried something like
mockAction.Stub(a => a.AddLink(null)).IgnoreArguments().Do(null);
before I go into the execution but this doesn't seem to work(I only get some exceptions). Any ideas and probably an explanation why the mock is executing the method logic at all ?
I've tried to reproduce. Here is the code which works fine for me
[Test]
public void Test()
{
var classMock = MockRepository.GenerateMock<MyClass>();
var linkedMock = MockRepository.GenerateStub<MyClass>();
classMock.Expect(c => c.MyMethod(linkedMock));
classMock.MyMethod(linkedMock);
classMock.AssertWasCalled(c => c.MyMethod(linkedMock));
}
public class MyClass
{
public virtual void MyMethod(MyClass linkedClass)
{
Console.WriteLine("MyMethod is called");
}
}
Your approach will only work if your method AddLink is virtual, otherwise the .Net runtime will always run the real implementation (and rightly so).
Usually the best practise is to use interfaces when doing dependency injection (so your class expects IMyClass instead of MyClass). This way it is much easier to use mocking frameworks - not only you don't have to remember to make all methods virtual, but you avoid the issues with passing correct arguments to MyClass's constructor (which in real world is a pain)