Skip to content

Instantly share code, notes, and snippets.

@bartelink
Created November 5, 2010 12:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bartelink/664092 to your computer and use it in GitHub Desktop.
Save bartelink/664092 to your computer and use it in GitHub Desktop.
Demonstrates bitbucket.org/johannesrudolph/subspec/overview
1. uses a ContextFixture (which requires Disposal)
2. keeps all Context/ContextFixture+Do+Assert/Observation in a single Test Method at all costs -- lambdas get very yucky the minute you factor calls to any of these into test methods
3. The TheoryDataProvider junk at the end is also applicable to xUnit [Theory] stuff (and you use the same [ClassData] and friends as one uses for other xunit.net stuff and just removes some cruft from writing up test cases)
4. uses sut/result/exception standard names
5. This is a sample and has stuff that doesnt scale up that I wouldnt do. e.g. dont use Conditional Logic in tests with care - something as simple as a should succeed / should fail set of cases should generally be two separate Thesis methods
Go look in bitbucket - there's a good set of tests that serve as a better set of samples.
This snippet will self destruct when someone tells me that the acceptance tests and samples in Johannes' fork are clearer and more complete
public class ThesisExample
{
public class Cases : TheoryDataProvider
{
protected override IEnumerable<object[]> DataSource()
{
yield return new object[] { "A", "a", true };
yield return new object[] { "B", null, false };
}
}
[Thesis]
[ClassData( typeof( Cases ) )]
public static void StuffMatchingACases( string input, string output, bool shouldSucceed )
{
var sut = default( AMangler );
"Given a mangler"
.ContextFixture( () =>
sut = new AMangler() );
var exception = default( Exception );
var result = default( string );
("Mangling " + input)
.Do( () =>
exception = Record.Exception( () =>
result = sut.Match( input ) ) );
if ( shouldSucceed )
"is handled correctly"
.Observation( () =>
Assert.Equal( output, result ) );
else
"is rejected"
.Observation( () =>
Assert.IsType<ArgumentException>( exception ) );
}
class AMangler : IDisposable
{
public string Match( string param )
{
if ( param != "A" )
throw new ArgumentException( "don't like it" );
return param.ToLower();
}
void IDisposable.Dispose()
{
Console.WriteLine( "Disposing" );
}
}
public abstract class TheoryDataProvider : IEnumerable<object[]>
{
protected abstract IEnumerable<object[]> DataSource();
public IEnumerator<object[]> GetEnumerator()
{
return DataSource().GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return DataSource().GetEnumerator();
}
}
public abstract class SingleItemTheoryDataProvider : TheoryDataProvider
{
protected override sealed IEnumerable<object[]> DataSource()
{
return SingleItemDataSource().Select( x => new object[] { x } );
}
protected abstract IEnumerable<object> SingleItemDataSource();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment