Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

An assertions framework for .NET with a BDD-like feel, inspired by Chai and Jasmine, designed to be user-extensible

License

NotificationsYou must be signed in to change notification settings

fluffynuts/NExpect

Repository files navigation

An assertions framework for .NET with a BDD-like feel, inspired by Chai and Jasmine, designed to be user-extensible

Build and Test

Nuget current version badge

Goals

  • Expect(NExpect).To.Be.Readable();
    • Because code is for co-workers, not compilers. And your tests are part of your documentation.
  • Expect(NExpect).To.Be.Expressive();
    • Because the intent of a test should be easy to understand. The reader can delve into the details when she cares to.
  • Expect(NExpect).To.Be.Extensible();
    • Because I can't predict every use-case. I believe that your assertions framework should enable expressive, readable tests through extension.

Tutorial / blog posts:

https://fluffynuts.github.io/NExpectdev.to

Usage

  1. Download fromnuget.org:install-package nexpect
  2. Import Expectations statically:
usingstaticNExpect.Expectations;
  1. Expect inside your tests, with fluent syntax:
// simple equality checksExpect(1).To.Equal(1);Expect(true).To.Not.Be.False();// alt. grammarExpect(null).To.Be.Null();// - with negation, order doesn't matterExpect("moo").Not.To.Equal("cow");Expect("moo").To.Not.Equal("cow");Expect(true).Not.To.Be.False();Expect(false).To.Not.Be.True();// exceptionsExpect(()=>{}).Not.To.Throw();Expect(()=>{thrownewArgumentException("moo","moo cow");}).To.Throw<ArgumentException>().With.Message.Containing("moo").And.("cow");// smarter string tests, with fluencyExpect(someString).To.Contain("moo").And("cow");Expect("moo, said the cow").To.Start.With("moo").And.Contain("said").Then("the").And.End.With("cow");// collection testsExpect(someCollection).To.Contain.Exactly(2).Matched.By(item=>item.IsWhatWeWant());Expect(someCollection).To.Contain.Only(1).Deep.Equal.To(new{id=42,name="Douglas"});Expect(someFlags).To.Contain.At.Least(3).Equal.To(true);Expect(new[]{1,2,3}).To.Be.Ordered.Ascending();Expect(new[]{"c","b","a"}).To.Be.Ordered.Descending();// type testingExpect(someObject).To.Be.An.Instance.Of<Cow>();// deep and intersection equality testingvarperson=new{id=1,name="bob"};Expect(person).To.Deep.Equal(new{id=1,name="bob"});Expect(person).To.Intersection.Equal(new{name="bob"});// deep equality testing with excluded propsExpect(person).To.Deep.Equal(new{id=1,name="sarah"},exclude:["name"]);// orExpect(person).Omitting("name").To.Deep.Equal(new{id=1,name="sipho"});

Extending

Mostly, you can extend by adding extension methods for ICanAddMatcher where T is thetype you want. You can also extend at any point in the grammar -- some of the "better"points are ITo, IBe, IHave, IA, IAn. You will need another namespace import:

usingNExpect.MatcherLogic

And your extension methods can be like:

publicstaticclassMyMatchers{publicstaticvoidFive(thisIBe<int>continuation){continuation.AddMatcher(actual=>{varpassed=actual==5;varmessage=passed?$"Expected{actual} not to be 5":$"Expected{actual} to be 5";returnnewMatcherResult(passed,message);});}}
// somewhere else...[Test]publicvoidFifteenDividedByThree_ShouldEqual_Five(){varresult=15/3;Expect(result).To.Be.Five();}// Yes, yes, simple example is simple.

If you've ever written a Jasmine matcher, this should feel familiar.

If you have a bunch of existing expectations that you'd like to wrapup into a nicely-named matcher,.Compose has you covered:

// beforevarcow=animalFactory.MakeCow();varbeetle=animalFactory.MakeBeetle();// animal factory should make a Jersey cowExpect(cow.Classification).To.Equal("Mammal");Expect(cow.Legs).To.Equal(4);Expect(cow.HasTail).To.Be.True();Expect(cow.HasHorns).To.Be.True();Expect(cow.HasSpots).To.Be.True();// Animal factory should make a rhinoceros beetleExpect(beetle.Classification).To.Equal("Insect");Expect(beetle.Legs).To.Equal(6);Expect(beetle.HasTail).To.Be.False();Expect(beetle.HasHorns).To.Be.True();Expect(beetle.HasSpots).To.Be.False();
// aftervarcow=animalFactory.MakeJerseyCow();varbeetle=animalFactory.MakeRhinocerosBeetle();Expect(cow).To.Be.A.JerseyCow();Expect(beetle).To.Be.A.RhinocerosBeetle();// elsewhere:publicstaticclassAnimalMatchers{// the IMore<T> interface allows fluent chaining of expectations//  eg://  Expect(cow).To.Be.A.JerseyCow()//     .And//     .Not.To.Be.A.FrieslandCow();publicstaticIMore<Animal>JerseyCow(thisIA<Animal>a){returna.Compose(actual=>{Expect(cow.Classification).To.Equal("Mammal");Expect(cow.Legs).To.Equal(4);Expect(cow.HasTail).To.Be.True();Expect(cow.HasHorns).To.Be.True();Expect(cow.HasSpots).To.Be.True();});}publicstaticIMore<Animal>RhinocerosBeetle(thisIA<Animal>a){returna.Compose(actual=>{Expect(beetle.Classification).To.Equal("Insect");Expect(beetle.Legs).To.Equal(6);Expect(beetle.HasTail).To.Be.False();Expect(beetle.HasHorns).To.Be.True();Expect(beetle.HasSpots).To.Be.False();});}}

When one of the inner expectations fails, NExpect attempts to constructa nice failure message. As with all expectations, you can always makefailures easier to understand with a custom message string or generator:

usingNExpect.Implementations;usingNExpect.MatcherLogic;usingNExpect;usingstaticNExpect.Expectations;publicstaticclassAnimalMatchers{publicstaticIMore<Animal>JerseyCow(thisIA<Animal>a){returna.Compose(actual=>{// the Stringify extension method, available on all types,// comes from NExpect.Implementation.MessageHelpers and// produces a string representation of the object it's// operating on which is similar to JSON, so it's easier// to read what the object wasvarcustomMessage=$"Expected{actual.Stringify()} to be a cow";Expect(cow.Classification).To.Equal("Mammal",customMessage);Expect(cow.Legs).To.Equal(4,customMessage);Expect(cow.HasTail).To.Be.True(customMessage);Expect(cow.HasHorns).To.Be.True(customMessage);Expect(cow.HasSpots).To.Be.True(customMessage);});}publicstaticIMore<Animal>RhinocerosBeetle(thisIA<Animal>a){returna.Compose(actual=>{// we can use a generator func to delay generation of the message//  which is especially helpful if message generation is expensive//  and we'd only like to spend that cpu time on a failureFunc<string>customMessageGenerator=()=>$"Expected{actual.Stringify()} to be a cow";Expect(beetle.Classification).To.Equal("Insect",customMessageGenerator);Expect(beetle.Legs).To.Equal(6,customMessageGenerator);Expect(beetle.HasTail).To.Be.False(customMessageGenerator);Expect(beetle.HasHorns).To.Be.True(customMessageGenerator);Expect(beetle.HasSpots).To.Be.False(customMessageGenerator);});}}

About

An assertions framework for .NET with a BDD-like feel, inspired by Chai and Jasmine, designed to be user-extensible

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors7

Languages


[8]ページ先頭

©2009-2025 Movatter.jp