Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FsCheck generating test objects in C# #656

Closed
JaggerJo opened this issue Feb 8, 2024 · 5 comments
Closed

FsCheck generating test objects in C# #656

JaggerJo opened this issue Feb 8, 2024 · 5 comments

Comments

@JaggerJo
Copy link

JaggerJo commented Feb 8, 2024

Hi there 👋

I'm trying to generate a list of C# records as test data for a property based test, but face a few issues.

1. Nullable reference types

How can I configure the generator to respect nullability of reference types in C#?

FullName is not allowed to be null -> don't generate null values
Notes is allowed to be null -> generate null values

public record Customer 
{
    public string FullName { get; init; }
    public string? Notes { get; init }
}

2. Generating complex objects

Let's assume I need to generate random samples of the type below, but there are certain rules on what's valid input.

Example Rules:
Name: Any not null string
Shorthand: First 3 chars from Name, if Name is shorter then 3 then equal to Name.
InternalPhonePrefix: Any random string.

(excuse my silly examples 🙃)

public record Department 
{
    public string Name { get; init; }
    public string Shorthand { get; init }
    public string InternalPhonePrefix { get; init; }
}

I guess this would work, but is there a better way?

    public static Arbitrary<Department> RandomDepartment() =>
        Arb.Generate<(string, string, string)>()
            .Select(department => new Department
            {
                Name = department.Item1,
                Shorthand = department.Item2,
                InternalPhonePrefix = department.Item3
            })
            .ToArbitrary();
@BennieCopeland
Copy link
Contributor

For number 2, you can use the query syntax

var generator =
    from name in Arb.Generate<string>()
    from phone in Arb.Generate<string>()
    select new Department
    {
        Name = name,
        Shorthand = name.Substring(0, 2),
        InternalPhonePrefix = phone
    }

@JaggerJo
Copy link
Author

JaggerJo commented Feb 8, 2024

For number 2, you can use the query syntax

var generator =
    from name in Arb.Generate<string>()
    from phone in Arb.Generate<string>()
    select new Department
    {
        Name = name,
        Shorthand = name.Substring(0, 2),
        InternalPhonePrefix = phone
    }

Thanks! That's quite handy

@BennieCopeland
Copy link
Contributor

It's also useful if you're using the CSharpFunctionalExtensions nuget package. You can do the same thing with a bunch of Result's or Maybe's. Not as good as a computation expression in F#, but it gets the job done.

@kurtschelfthout
Copy link
Member

Nullable reference types

FsCheck cannot currently do this, based on the type alone. From a quick searc, since .NET 6 or 7 we can check the nullability of a type at runtime, so this may be possible to implement via that route.

Generating complex objects

@BennieCopeland's is probably the best way to do that.

@JaggerJo
Copy link
Author

Nullable reference types

FsCheck cannot currently do this, based on the type alone. From a quick searc, since .NET 6 or 7 we can check the nullability of a type at runtime, so this may be possible to implement via that route.

Interesting 👍

Generating complex objects

@BennieCopeland's is probably the best way to do that.

Yup, that actually works pretty well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants