question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

ImmutableDictionary regression in 2.7

See original GitHub issue

Hello,

In 2.7, AutoBogus throws an exception when using AutoFaker.Generate<T>() with classes that expose an ImmutableDictionary<T,U> as a public property. In 2.6, such classes used to be able to generate without having to skip these properties - they would just be null.

This also seems to happen with ReadOnlyDictionary<T,U>, which is a regression - in 2.6, a ReadOnlyDictionary would work and be faked correctly.

The regression can be worked-around by calling WithSkip in AutoFaker.Configure.

The below console app demonstrates the issue. If you install the 2.6.0 AutoBogus package, it runs and produces the below output (the immutable dictionary is left as null). If you update to 2.7.0 or beyond, it crashes with one of the exceptions below. Skipping both the ReadOnlyDictionary and ImmutableDictionary works around the problem.

SomeStringProperty = JSON
SomeReadOnlyDictionary = System.Collections.ObjectModel.ReadOnlyDictionary`2[System.String,System.String]
SomeReadOnlyDictionary Count = 3
SomeImmutableDictionary =
SomeImmutableDictionary Count =

In 2.7.0 and after, it crashes with an exception. Even if you skip the immutable dictionary property, it still crashes when trying to call Add.

Example of exception for converting to ReadOnlyDictionary<T,U>:

System.ArgumentException
  HResult=0x80070057
  Message=Object of type 'System.Collections.Generic.Dictionary`2[System.String,System.String]' cannot be converted to type 'System.Collections.ObjectModel.ReadOnlyDictionary`2[System.String,System.String]'.
  Source=System.Private.CoreLib
  StackTrace:
   at System.RuntimeType.TryChangeType(Object value, Binder binder, CultureInfo culture, Boolean needsSpecialCast)
   at System.RuntimeType.CheckValue(Object value, Binder binder, CultureInfo culture, BindingFlags invokeAttr)
   at System.Reflection.MethodBase.CheckArguments(Object[] parameters, Binder binder, BindingFlags invokeAttr, CultureInfo culture, Signature sig)
   at System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
   at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, Object[] index)
   at AutoBogus.AutoMember.<>c__DisplayClass0_0.<.ctor>b__1(Object obj, Object value)
   at AutoBogus.AutoBinder.PopulateInstance[TType](Object instance, AutoGenerateContext context, IEnumerable`1 members)
   at AutoBogus.Generators.TypeGenerator`1.AutoBogus.IAutoGenerator.Generate(AutoGenerateContext context)
   at AutoBogus.AutoGenerateContextExtensions.Generate[TType](AutoGenerateContext context)
   at AutoBogus.AutoFaker.AutoBogus.IAutoFaker.Generate[TType](Action`1 configure)
   at AutoBogus.AutoFaker.Generate[TType](Action`1 configure)
   at AutoBogusImmutableIssue.Program.Main(String[] args) in C:\Users\SteveOgnibene\source\repos\AutoBogusImmutableIssue\AutoBogusImmutableIssue\Program.cs:line 21

Example of exception for converting to ImmutableDictionary<T,U>:

System.ArgumentException
  HResult=0x80070057
  Message=Object of type 'System.Collections.Generic.Dictionary`2[System.String,System.String]' cannot be converted to type 'System.Collections.Immutable.ImmutableDictionary`2[System.String,System.String]'.
  Source=System.Private.CoreLib
  StackTrace:
   at System.RuntimeType.TryChangeType(Object value, Binder binder, CultureInfo culture, Boolean needsSpecialCast)
   at System.RuntimeType.CheckValue(Object value, Binder binder, CultureInfo culture, BindingFlags invokeAttr)
   at System.Reflection.MethodBase.CheckArguments(Object[] parameters, Binder binder, BindingFlags invokeAttr, CultureInfo culture, Signature sig)
   at System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
   at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, Object[] index)
   at AutoBogus.AutoMember.<>c__DisplayClass0_0.<.ctor>b__1(Object obj, Object value)
   at AutoBogus.AutoBinder.PopulateInstance[TType](Object instance, AutoGenerateContext context, IEnumerable`1 members)
   at AutoBogus.Generators.TypeGenerator`1.AutoBogus.IAutoGenerator.Generate(AutoGenerateContext context)
   at AutoBogus.AutoGenerateContextExtensions.Generate[TType](AutoGenerateContext context)
   at AutoBogus.AutoFaker.AutoBogus.IAutoFaker.Generate[TType](Action`1 configure)
   at AutoBogus.AutoFaker.Generate[TType](Action`1 configure)
   at AutoBogusImmutableIssue.Program.Main(String[] args) in C:\Users\SteveOgnibene\source\repos\AutoBogusImmutableIssue\AutoBogusImmutableIssue\Program.cs:line 11

Demo program:

using AutoBogus;
using System;
using System.Collections.Immutable;
using System.Collections.ObjectModel;

namespace AutoBogusImmutableIssue
{
    class Program
    {
        static void Main(string[] args)
        {
            //AutoFaker.Configure(builder =>
            //{
              //  builder
              //  .WithSkip<MyClass>(mc => mc.SomeImmutableDictionary)
              //  .WithSkip<MyClass>(mc => mc.SomeReadOnlyDictionary)
             //   ;
            //});

            var myInstance = AutoFaker.Generate<MyClass>();
            Console.WriteLine($"{nameof(MyClass.SomeStringProperty)} = {myInstance.SomeStringProperty}");
            Console.WriteLine($"{nameof(MyClass.SomeReadOnlyDictionary)} = {myInstance.SomeReadOnlyDictionary}");
            Console.WriteLine($"{nameof(MyClass.SomeReadOnlyDictionary)} Count = {myInstance.SomeReadOnlyDictionary?.Count}");
            Console.WriteLine($"{nameof(MyClass.SomeImmutableDictionary)} = {myInstance.SomeImmutableDictionary}");
            Console.WriteLine($"{nameof(MyClass.SomeImmutableDictionary)} Count = {myInstance.SomeImmutableDictionary?.Count}");

        }
    }

    public class MyClass
    {
        public string SomeStringProperty { get; set; }
        public ReadOnlyDictionary<string, string> SomeReadOnlyDictionary { get; set; }
        public ImmutableDictionary<string, string> SomeImmutableDictionary { get; set; }
    }
}

I’m willing to give it a shot to fix this if you can come up with a good idea. I can try bisecting if you think that would be valuable. Thanks for this great library.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:13 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
nickdodd79commented, Jan 2, 2020

Hey @kevin-david

I have now got IReadOnlyDictionary<T,U> working again. Turns out some of my tests weren’t executing which would have highlighted the issue. A new version will be available shortly.

Hey @nycdotnet

I can’t get ImmutableDictionary to work as expected because the AutoBogus code runs on .NET Standard, but ImmutableDictionary seems to only be available in .NET Core.

https://docs.microsoft.com/en-us/dotnet/api/system.collections.immutable.immutabledictionary-2?view=netcore-2.0

I do have plans for a big refactor of AutoBogus (v3) to cater for this, which I am currently working on.

However, I did wonder how you managed to get it working in v2.6, so I checked out that version of the code to run some tests. Do your properties populate as expected, because when I run my test code, the ImmutableDictionary property is always null. As far as I can tell ImmutableDictionary instances need to be created using static factory methods on the class (which AutoBogus doesn’t know about to create an instance).

Nick.

1reaction
nickdodd79commented, Dec 4, 2019

Hi @nycdotnet

Thanks for the details above. I am surprised you are seeing an issue with ReadOnlyDictionary. That type should be handled, so I will need to investigate further.

With the ImmutableDictionary that could possibly be a special case that doesn’t follow the supported collection interfaces. Again, I will need to investigate to see why.

Watch this space 😄

Nick.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How To Conquer The 2.5 Year Sleep Regression (and why it ...
A sleep regression occurs when a baby or toddler that normally sleeps well begins waking frequently through the night, or refuses naps. You...
Read more >
ImmutableDictionary<TKey,TValue> Class
Represents an immutable, unordered collection of keys and values. NuGet package: System.Collections.Immutable (about immutable collections and how to ...
Read more >
2 Year Old Sleep Regression: Reasons, Signs & Solutions
“The two year old sleep regression can manifest in challenges falling asleep at bedtime, night waking or early wake ups”. · Suddenly they...
Read more >
How To Survive The 2.5 Year Sleep Regression
You're not alone in the battle against the dreaded 2.5 year sleep regression! Here are some tips and tricks to help you and...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found