Reputation: 403
As shown in the image, I want to fake extension method (seen in Specflow's ScenarioContext class) : public bool TryGetValue<TValue>(string key, out TValue value)
I've created fakes for the System.Collection assembly (which contains the IDictionary extension method), but I do not understand how to fake a function which has parameters. I do know how to fake for a parameterless function such as the File.IO.ReadAllLines() function :
using (ShimsContext.Create())
{
System.IO.ShimFile.ReadAllLines = m => new string[]{};
....
Can I get help understanding how to mock this extension method: System.Collections.Generic.CollectionExtensions.GetValueOrDefault
... I honestly tried looking for examples, but the only ones I could find were parameterless functions or getters.
Upvotes: -2
Views: 640
Reputation: 9471
Here's a distinction that may be of use to you: Given a choice of extensions, the compiler will choose the more-constrained version. So for example if you wantGetValueOrDefault()
to return a mocked result for a SpecFlowContext
then make an extension for this SpecFlowContext
.
static class Extensions
{
public static object GetValueOrDefault<TKey>(
this SpecFlowContext dictionary,
TKey key) where TKey : notnull
{
return "Fake value A";
}
public static object GetValueOrDefault<TKey, TValue>(
this SpecFlowContext dictionary,
TKey key,
[AllowNull] TValue defaultValue)
{
if(defaultValue is string valid)
{
return valid;
}
return "Fake value B";
}
}
TEST
class Program
{
static void Main(string[] args)
{
// Normal dictionary
var normal = new Dictionary<string, object>
{
{ "Apple", "Red" },
{ "Orange", "Orange" },
};
Console.WriteLine(normal.GetValueOrDefault("Apple"));
// SpecFlowContext dictionary
var fake = new CustomSpecFlowContext
{
{ "Apple", "Red" },
{ "Orange", "Orange" },
};
Console.WriteLine(fake.GetValueOrDefault("Apple"));
Console.WriteLine(fake.GetValueOrDefault("Apple", (string)null));
Console.WriteLine(fake.GetValueOrDefault("Apple", "Fake value C"));
}
}
// Class that implements abstract SpecFlowCOntext
class CustomSpecFlowContext : SpecFlowContext { }
Upvotes: 0
Reputation: 36659
I would assume you are talking about Microsoft Fakes.
To provide a fake implementation of a method with parameters the documentation specifies the following:
Name is original name + parameter types:
So for ReadAllLines I would expect the name to be ReadAllLinesString
. Your editor should be able to show you what delegates are available to assign to.
But this is not an extension method, just a regular static method. You would typically not mock extension methods, since these are just providing extra functionality. Mock the underlying type instead.
In the case of CollectionExtensions.GetValueOrDefault I would argue that you should mock the underlying Dictionary.TryGetValue
that I assume GetValueOrDefault uses. I would however argue that faking or mocking collections is not very useful. Mocking tend to be most useful when used on the "edges" of some module, like replacing file system functions as an example. Collections are a fairly integral part of .Net, so there is much less to be gained by trying to mock them, IMHO.
Upvotes: 1