moq icon indicating copy to clipboard operation
moq copied to clipboard

Default value ILookup<> in loose mode is `null`

Open ggirard07 opened this issue 2 years ago • 1 comments

Based on wiki, and as ILookup<> inherits from IEnumerable<>, I would expect the default value in loose mode to be an empty lookup, not null.

returns default values or empty arrays, enumerables, etc

Am I missing something here?

ggirard07 avatar Aug 11 '23 15:08 ggirard07

Hi @ggirard07, IIRC the code behind DefaultValue.Empty performs a strict type check and doesn't take type inheritance into account.

Before you ask: yes, of course this could be changed. We've had similar requests in the past. (If I find the time, I'll link to some of them later.) However, I have been hesitant to change the behavior of DefaultValue.Empty because it is a core part of Moq and functional changes to it it could affect much pre-existing user code.

Now that Moq vNext has been shelved (for the time being) and we're free to do a new major version, perhaps we'll be able to change that behavior in v5.

stakx avatar Aug 11 '23 18:08 stakx

The following (partially) works as long as the signature of the method being invoked clearly uses ILookup<> (i.e. won't work with IServiceProvider since the return type isn't known):

using Moq;
using Xunit;

var mock = new Mock<ILookupProvider>();
mock.SetReturnsDefault(new Dictionary<string, string>().ToLookup(x => x.Key, x => x.Value));

var lookup = mock.Object.GetLookup<string, string>();

Assert.NotNull(lookup);

public interface ILookupProvider
{
    ILookup<TKey, TValue> GetLookup<TKey, TValue>();
}

kzu avatar Jun 15 '24 05:06 kzu