5

I have an object containing a char property. For my test, I need to have that property set to anything but I or R. Is there anything, ideally native to AutoFixture, that I could do to have cleaner, briefer code than what I came up with?

This is a representation of the object

public class MyObject
{
    public char MyProperty {get; set;}
}

And the solution I'm using

MyObject = _fixture.Create<MyType>();
if ((new char[] { 'I', 'R' }).Contains(MyObject.MyProperty))
    MyObject.MyProperty = new Generator<char>(_fixture).Where(c => !new char[] { 'I', 'R' }.Contains(c)).First();
LPLN
  • 475
  • 1
  • 6
  • 20
bkqc
  • 831
  • 6
  • 25
  • Seems rather a codereview question in case you are just looking for optimizations of working code. It might be a bit short though :) – Icepickle Dec 11 '19 at 15:24
  • 1
    You can create custom `RandomCharSequenceGenerator` https://github.com/AutoFixture/AutoFixture/blob/master/Src/AutoFixture/RandomCharSequenceGenerator.cs, but it won't be more concise. So if that's the only place you need it, I wouldn't go with it. Let me know if you want an example. – Andrii Litvinov Dec 11 '19 at 15:24

2 Answers2

5

ElementsBuilder seems like a good candidate here, so long as you're willing to create a whilelist of acceptable characters, rather than a blacklist.

Here's a quick sample, using your MyObject definition.

var fixture = new Fixture();

// A-Z, minus I, R.
fixture.Customizations.Add(new ElementsBuilder<char>("ABCDEFGHJKLMNOPQSTUVWXYZ"));

var createdCharacters = fixture
                .Create<Generator<MyObject>>() 
                .Take(1000)                    
                .Select(f => f.MyProperty)     
                .ToList();          

CollectionAssert.DoesNotContain(createdCharacters, 'I');
CollectionAssert.DoesNotContain(createdCharacters, 'R');

If you need any more nuance than that (e.g., other objects can use I or R characters), a custom ISpecimenBuilder is the way to go.

Jeff Dammeyer
  • 656
  • 6
  • 16
1

I recommend using custom initialization logic with the Fixture.Customize<T>() method, this give you an instance of your type composer and let's you set values for T's properties. This has the added benefit of restricting the logic to a specific type, unlike ElementBuilder which will generate chars for every type.

fixture.Customize<MyType>(composer => composer.With(myType => myType.MyProperty, "[custom value]"));
sspaniel
  • 647
  • 3
  • 10