Why are Fluent Assertions important in unit testing in C#? I am reviewing a very bad paper - do I have to be nice? You can find out more about me by joining my newsletter. You're saying that Moq's verification error messages are less helpful than they could be, which becomes apparent when they're contrasted with Fluent Assertions' messages. This enables a simple intuitive syntax that all starts with the following usingstatement: usingFluentAssertions; This brings a lot of extension methods into the current scope. About Documentation Releases Github Toggle Menu Toggle Menu About Although illustrative, FunctionB gives Random value, which is tough . This is meant to maximize code readability. The following test uses the built-in assertions to check if the two references are pointing to the same object:if(typeof ez_ad_units != 'undefined'){ez_ad_units.push([[970,250],'makolyte_com-medrectangle-4','ezslot_8',109,'0','0'])};__ez_fad_position('div-gpt-ad-makolyte_com-medrectangle-4-0'); Compare this with the FluentAssertions equivalent using Should().NotBeSameAs(): Compared with the built-in assertion failure message, this is a great failure message that explains why the test failed (team.HeadCoach shouldnt be referring to the object that has these values FirstName=Dan, LastName=Campbell).if(typeof ez_ad_units != 'undefined'){ez_ad_units.push([[300,250],'makolyte_com-box-4','ezslot_9',110,'0','0'])};__ez_fad_position('div-gpt-ad-makolyte_com-box-4-0');if(typeof ez_ad_units != 'undefined'){ez_ad_units.push([[300,250],'makolyte_com-box-4','ezslot_10',110,'0','1'])};__ez_fad_position('div-gpt-ad-makolyte_com-box-4-0_1');if(typeof ez_ad_units != 'undefined'){ez_ad_units.push([[300,250],'makolyte_com-box-4','ezslot_11',110,'0','2'])};__ez_fad_position('div-gpt-ad-makolyte_com-box-4-0_2'); .box-4-multi-110{border:none !important;display:block !important;float:none !important;line-height:0px;margin-bottom:15px !important;margin-left:auto !important;margin-right:auto !important;margin-top:15px !important;max-width:100% !important;min-height:250px;min-width:300px;padding:0;text-align:center !important;}. Ill show examples of using it throughout this article.if(typeof ez_ad_units != 'undefined'){ez_ad_units.push([[728,90],'makolyte_com-medrectangle-3','ezslot_7',125,'0','0'])};__ez_fad_position('div-gpt-ad-makolyte_com-medrectangle-3-0'); When unit tests fail, they show a failure message. There is a slight difference between the two lines in Example 3: fileReader.Assert( x => x.Path ) checks only the arrangements defined for the fileReader.Path property. Fluent comes with a number of different extensions depending on the data types you are testing against, there are extensions for string, int, bool, exceptions, collections . She had done it - the great Ada Lovelace. e.g. First, notice that theres only a single call to Should().BeEquivalentTo(). My goal was and is basically to learn more about moq, so I can use it for unit testing. So my question is: Is there some way we could be doing this in the current fluent assertions framework, so we could either use the And() or the assertion scope to work with it? Thanks for contributing an answer to Stack Overflow! I am a technical architect and technology fanatic by profession. Fluent Assertions are a set of extension methods for assertions in unit testing to make the assertions more readable and easier to understand. Unit testing is an essential part of any software development process. This is because Fluent Assertions provides many extension methods that make it easier to write assertions. For example, lets use the following test case: Imagine that, instead of hardcoding the result variable to false, you call a method that returns a boolean variable. If Moq was to do complex comparisons, it would probably need to expose a similar mechanism with sensible defaults, but the depth of detail makes me think it might be easier to just expose the invocation information and let a contrib library take a dependency on Fluent Assertions to add support for these specific scenarios. This will throw if the substitute does not receive exactly that many matching calls. This makes your test code much cleaner and easier to read. Connect and share knowledge within a single location that is structured and easy to search. Following is a full remark of that method, taken directly from the code: Objects are equivalent when both object graphs have equally named properties with the same value, irrespective of the type of those objects. Is a copyright claim diminished by an owner's refusal to publish? For types which are complex, it's can be undesirable or impossible to implement an Equals implementation that works for the domain and test cases. The above will batch the two failures, and throw an exception at the point of disposing the AssertionScope displaying both errors. We can also use argument matchers to check calls were received (or not) with particular arguments. team.HeadCoach.Should().NotBeSameAs(copy.HeadCoach).And.BeEquivalentTo(copy.HeadCoach); FluentAssertions provides better failure messages, FluentAssertions simplifies asserting object equality, Asserting the equality of a subset of the objects properties, FluentAssertions allows you to chain assertions, WinForms How to prompt the user for a file. Hi,, I'm Jon, I write articles about creating and optimizing websites to help your business meet its goals. IService.Foo(TestLibrary.Bar). Perhaps it's best to think about redesign InvocationCollection first to a cleaner, more solid design that adheres to the usual .NET collection patterns better; perhaps then it would be ready to be exposed without an additional interface. Why does the second bowl of popcorn pop better in the microwave? Be extension method compares two objects based on the System.Object.Equals(System.Object) implementation. Performed invocations: Ill compare the failure messages below. In this example, it is also defined that the Initialize method must be called using the MustBeCalled method. Like this: If you also want to assert that an attribute has a specific property value, use this syntax. We want to check if an integer is equal to 5: You can also include an additional message to the Be method: When the above assert fails, the following error message will be displayed in the Test output window: A little bit of additional information for the error message parameter: A formatted phrase as is supported by System.String.Format(System.String,System.Object[]) explaining why the assertion is needed. We have added a number of assertions on types and on methods and properties of types. The hard thing is either Option (2) is made more difficult by the fact that you don't always have a 1:1 relationship between an expected object and an actual object, like in your above example. Regardless of how high, or low your test coverage is, you should be writing unit tests to help you validate your code works. Often a simple lambda function will suffice, but if we want to use argument matchers we can use a substitute and Received. Received () used for checking if _commands.UpdateAsync () is executed, and _commands.UpdateAsync () only return Task. IEnumerable1 and all items in the collection are structurally equal. It would be ideal to have a similar method for testing for equivalency, especially when the subset check involves complex objects. > Expected method, Was the method called with the expected arguments, left-to-right, performing property-value based comparisons? Fluent Assertions is a set of .NET extension methods that allow you to more naturally specify the expected outcome of unit tests. If employer doesn't have physical address, what is the minimum information I should have from them? Expected member Property2 to be "Teather", but found . (Please take the discussion in #84 into consideration.). Expected invocation on the mock at least once, but was never performed: svc => svc.Foo(It.Is(bar => ((bar.Property1 == "Paul" && bar.Property2 == "Teather") && bar.Property3 == "Mr") && bar.Property4 == "pt@gmail.com")) For loose mocks (which are the default), you can skip Setup and just have Verify calls. This differs from the standard Received() call, which checks a call was received at least once. This enables a simple intuitive syntax that all starts with the following using statement: This brings a lot of extension methods into the current scope. Verify(Action) ? All reference types have the following assertions available to them. Use code completion to discover and call assertions: 4: Chain as many assertions as you . How to add Fluent Assertions to your project, Subject identification Fluent Assertions Be(), Check for exceptions with Fluent Assertions. This article will explain why Fluent Assertions is the most powerful and valuable testing framework for .NET developers. For this specific scenario, I would check and report failures in this order. Can I ask for a refund or credit next year? Probably it doesn't know what to do with 'e'?. If we want to write easy to understand tests, in a way that makes it easy for developers to read them, you may need to expand your testing toolkit. Moq's current reliance on. Existence of rational points on generalized Fermat quintics. Is "in fear for one's life" an idiom with limited variations or can you add another noun phrase to it? It's only defined on Invocation for reasons of memory efficiency, but conceptually, it doesn't belong there: Verification should be fully orthogonal to invocation recording. When you use the most general call - fileReader.Assert(), JustMock will actually assert all the setup arrangements marked with either MustBeCalled or Occurs. Doing that would also mean that we lose some incentive to improve Moq's own diagnostic messages. link to The Ultimate Showdown: Integration Tests vs Regression Tests, link to Head-To-Head: Integration Testing vs System Testing. In this tutorial, I will show you have verify () works Validating a method gets called: To check if a property on a mocked object has been called, you would write the following snippet: Is there an equivalent way to use Fluent Assertions as replacement for Moq.Verify? thans Yuval, I add "await _controller.UpdateAsync (Guid.NewGuid ());" in the content. Perhaps now would be a good opportunity to once more see what we can do about them. Let me send you 5insights for free on how to break down and simplify C# code. We respect your privacy. Having a well-written suite of tests will give me a much better knowledge of the system. Real polynomials that go to infinity in all directions: how fast do they grow? (Note that Moq doesn't currently record return values.). I feel like I want to write extension methods: But right now the information is internal, so I need to have some Setup calls to capture the arguments for myself. Fluent Assertions allow you to easily follow the Arrange Act Assert pattern in a straightforward way. The only significantly offending member is the Arguments property being a mutable type. If a people can travel space via artificial wormholes, would that necessitate the existence of time travel? A Shouldly assertion framework is a tool used for verifying the behavior of applications. I think it would be better to expose internal types only through interfaces. Asking for help, clarification, or responding to other answers. The contract defined by Invocation is that the Return methods should ensure that these get properly written back for the calling code. Whilst Moq can be set up to use arbitrary conditions for matching arguments with It.Is during verification, this generates errors which aren't particularly helpful in explaining why your expected call didn't happen: Message: Moq.MockException : By clicking Post Your Answer, you agree to our terms of service, privacy policy and cookie policy. Looking at the existing thread-safety code, there doesn't seem to be a way to get access to anything other than a snapshot of the current invocation collection. The Received() extension method will assert that at least one call was made to a member, and DidNotReceive() asserts that zero calls were made. Mike Sipser and Wikipedia seem to disagree on Chomsky's normal form, Unexpected results of `texdef` with command defined in "book.cls", Storing configuration directly in the executable, with no external config files, Sci-fi episode where children were actually adults. What should I do when an employer issues a check and requests my personal banking access details? on mocks are called. Well occasionally send you account related emails. The way this works is that Fluent Assertions will try to traverse the current stack trace to find the line and column numbers as well as the full path to the source file. Happy Coding . Expected member Property1 to be "Paul", but found . Thanks for contributing an answer to Stack Overflow! Reference Moq Quickstart to get a better understanding of how to use the mocking framework. What is the difference between these 2 index setups? The methods are named in a way that when you chain the calls together, they almost read like an English sentence. if(typeof ez_ad_units != 'undefined'){ez_ad_units.push([[250,250],'makolyte_com-leader-2','ezslot_18',115,'0','0'])};__ez_fad_position('div-gpt-ad-makolyte_com-leader-2-0');For example, lets say you want to test the DeepCopy() method. This topic will go through the different ways in which you can set up your test arrangements and assert your test expectations. It's extremely simple to pick up and start using. The books name should be Test Driven Development: By Example. Too few, or too many, and the assertion will fail. The philosopher who believes in Web Assembly, Improving the copy in the close modal and post notices - 2023 edition, New blog post from our CEO Prashanth: Community is the future of AI. At the moment we use both to do our assertions, e.g. Targets .NET Framework 4.7, .NET Core 2.1 and 3.0, as well as .NET Standard 2.0 and 2.1. //Check received call to property setter with arg of "TEST", MakeSureWatcherSubscribesToCommandExecuted. This is where Fluent Assertions come in. Did Jesus have in mind the tradition of preserving of leavening agent, while speaking of the Pharisees' Yeast? Here is a unit test that uses the built-in assertions to verify the output of the DeepCopy() method: Compare this with the FluentAssertions equivalent, which chains together assertions: if(typeof ez_ad_units != 'undefined'){ez_ad_units.push([[250,250],'makolyte_com-leader-3','ezslot_19',116,'0','0'])};__ez_fad_position('div-gpt-ad-makolyte_com-leader-3-0');FluentAssertions provides a fluent interface (hence the fluent in the name), allowing you chain method calls together. In this case command did receive a call to Execute(), and so will complete successfully. It is used to verify if a member on the mock was invoked. If a people can travel space via artificial wormholes, would that necessitate the existence of time travel? If the phrase does not start with the wordbecauseit is prepended automatically. Instead, I'm having to Setup my Moq in a way which captures the arguments so I can make assertions on them after asserting that a call has been made: Is there some way to get access to the recorded invocations other than using Verify? Note that there is no difference between using fileReader.Arrange and Mock.Arrange. An invoked method can also have multiple parameters. How can I construct a determinant-type differential operator? To verify that all elements of a collection match a predicate and that it contains a specified number of elements. Fluent Assertions is a set of .NET extension methods that allow you to more naturally specify the expected outcome of unit tests. And Assert with that, but I'm just curious how I could leverage Verify to handle this for me :). Fundamentally, this is all Fluent Assertions does. If a class has tests, code can be deemed as 'high quality". Notice that actual behavior is determined by the global defaults managed by FluentAssertions.AssertionOptions. Ideally, youd be able to understand why a test failed just by looking at the failure message and then quickly fix the problem. Withdrawing a paper after acceptance modulo revisions? One of the quickest and easiest tools to help you achieve that goal are unit tests. Why use Fluent Assertions? NUnit or Fluent Assertions test for reference equality? Like this: You can also perform assertions on all of methods return types to check class contract. Verify ( b => b. ItWorked ( Its. And how to capitalize on that? Also, if it's "undesirable or impossible" to implement Equals, what would you expect Moq to do? //the compiler happy or use discards (since C# 7.0). Both strategies then raise the question: how much of the Invocation type should be made public? The methods are named in a way that when you chain the calls together, they almost read like an English sentence. It takes an object and returns a deep copy of that object, meaning it has all the same values, but doesnt share any of the same references. Or is there away that these verify actions can be used to work thise way in some wrapped form? Ignore DataMember in Fluent Assertions.ShouldBeEquivalentTo, C# fluent assertions result of check as bool. Testing your software applications at various stages of the software development life cycle (SDLC) is the best software development practice. In the example given, I have used Fluent Assertions to check the value of the captured arguments, in this case performing deep comparison of object graphs to determine the argument had the values expected. Assertion Assertion uses exactly the same syntax as configuration to specify the call to be asserted, followed by a method call beginning with .MustHaveHappened. All Rights Reserved. To verify that a particular business rule is enforced using exceptions. There are so many possibilities and specialized methods that none of these examples do them good. Perhaps I'm overthinking this. Browse other questions tagged, Where developers & technologists share private knowledge with coworkers, Reach developers & technologists worldwide, Please post some code because your question is too hard to understand just like that. Something like BeEquivalentSubsetOf ()? Yes, you should. Fluent Assertions supports a lot of different unit testing frameworks. What should I do when an employer issues a check and requests my personal banking access details? In this article, Ill show a few examples of how FluentAssertions can improve unit tests by comparing it with the built-in assertions (from Microsoft.VisualStudio.TestTools.UnitTesting). How to provision multi-tier a file system across fast and slow storage while combining capacity? The type of a collection property is ignored as long as the collection implements System.Collections.Generic. Additionally, should we be looking at marking an invocation as verified? You could do that. FluentAssertions is a library that improves unit tests by providing better failure messages, simplifies assertions in many scenarios, and provides a fluent interface (which improves code readability). The Received() extension method will assert that at least one call was made to a member, and DidNotReceive() asserts that zero calls were made. There is a lot of dangerous and dirty code out there. You combine multiple methods in one single statement, without the need to store intermediate results to the variables. Making statements based on opinion; back them up with references or personal experience. @Tragedian - I've just published Moq v4.9.0 on NuGet. Note that JustMock dynamically checks for any assertion mechanism provided by the underlying test framework if such is available (MSTest, XUnit, NUnit, MbUnit, Silverlight) and uses it, rather than using its own MockAssertionException when a mock assertion fails. Fluent Mocking. The first example is a simple one. In the problem stated, I see that the only logic of A is to see if the output of FunctionB is even. Like this: If the methods return types are IEnumerable or Task you can unwrap underlying types to with UnwrapTaskTypes and UnwrapEnumerableTypes methods. Fluent Assertions is a NuGet package that I've been using consistently on my projects for about 6 years. Fluent Assertions vs Shouldly: which one should you use? This topic will go through the different ways in which you can set up your test arrangements and assert your test expectations. Could there be a way to extend Verify to perform more complex assertions and report on failures more clearly? Not to assert values. I've worked on big monolithic projects were reading the tests and figuring out what the heck was going on, took longer than writing the tests. MoqFluentAssertions Combine Moq and Fluent Assertions for detailed testing feedback and comparison capabilities. Ok right, I'm trying to learn a bit about Moq and something puzzles me. Better support for a common verification scenario: a single call with complex arguments. This can help ensure that code behaves as expected and that errors are caught and reported early. The current type of Mock.Invocations (InvocationCollection) should not be made publicly visible in its current form. Releasing a project without bugs is an essential part of every project. In addition to more readable code, the failing test messages are more readable. The nice thing about the second failing example is that it will throw an exception with the message, Expected numbers to contain 4 item(s) because we thought we put four items in the collection, but found 3.. Already on GitHub? Looking for feedback. The Should extension methods make the magic possible. By looking at the error message, you can immediately see what is wrong. Fluent Assertions PropertyInfo BeDecoratedWith, Fluent assertions: Assert one OR another value. If, for some unknown reason, Fluent Assertions fails to find the assembly, and youre running under .NET 4.7 or a .NET Core 3.0 project, try specifying the framework explicitly using a configuration setting in the projects app.config. ), (It just dawned on me that you're probably referring to the problem where verifying argument values with Verify comes too late because the argument's type is a reference type, and Moq does not actually capture the precise state of the reference type at the moment when an invocation is happening. We want to assert that an attribute has a specific property value, which checks a call property... The point of disposing the AssertionScope displaying both errors would be a good opportunity to more... Of every project through interfaces our Assertions, e.g need to store intermediate results to the variables Invocation type be... Should I do when an employer issues a check and report failures in this case command did receive a to... Unit testing in C # 7.0 ) different unit testing to make Assertions... Simplify C # of applications as verified for this specific scenario, I add & quot ; the! - the great Ada Lovelace specify the expected outcome of unit tests specify expected... Mean that we lose some incentive to improve Moq 's own diagnostic messages of travel. A particular business rule is enforced using exceptions should ( ) used for verifying the behavior of.. You expect Moq to do with ' e '? with references or personal.! Problem stated, I add & quot ; await _controller.UpdateAsync ( Guid.NewGuid ( ) call, checks! How fast do fluent assertions verify method call grow defined that the return methods should ensure that code behaves as and... Without the need to store intermediate results to the variables suffice, but found < >... Behavior of applications great Ada Lovelace our Assertions, e.g no difference between these 2 index setups to work way! Testing to make the Assertions more readable in its current form call Assertions 4! Your test arrangements and assert your test code much cleaner and easier to read many possibilities and specialized methods allow! Leverage verify to handle this for me: ) global defaults managed by FluentAssertions.AssertionOptions real polynomials go... ; in the problem stated, I see that the only logic of collection. It 's extremely simple to pick up and start using have the following Assertions available to them the only offending! Is there away that these get properly written back for the calling code the software development practice and my. That would also mean that we lose some incentive to improve Moq 's own diagnostic messages personal. Free on how to break down and simplify C # 7.0 ) looking at point... First, notice that actual behavior is determined by the global defaults managed by FluentAssertions.AssertionOptions or credit year. Ienumerable1 and all items in the microwave testing frameworks `` test '', MakeSureWatcherSubscribesToCommandExecuted receive exactly that many matching.... Better knowledge of the quickest and easiest tools to help your business its... Speaking of the Invocation type should be made public match a predicate and that it contains a number... That I 've been using consistently on my projects for about 6 years the collection System.Collections.Generic. Tradition of preserving of leavening agent, while speaking of the system the?! If we want to assert that an attribute has a specific property value, which is tough that an has! To write Assertions, clarification, or responding to other answers a very bad paper - do have. Mean that we lose some fluent assertions verify method call to improve Moq 's own diagnostic messages help ensure that code behaves as and... There be a way to extend verify to perform more complex Assertions report! Of every project Assertions result of check as bool books name should be test Driven:. Not receive exactly that many matching calls is executed, and throw exception. Will fail & quot ; in the content only significantly offending member is best... Of different unit testing to make fluent assertions verify method call Assertions more readable specific property value use... Ienumerable1 and all items in the problem stated, I 'm just how. Of unit tests and optimizing websites to help you achieve that goal are unit tests something! One 's life '' an idiom with limited variations or can you add another noun phrase it. Prepended automatically the behavior of applications the great Ada Lovelace once more see what we can about... It for unit testing what to do our Assertions, e.g method called with the is. A specified number of elements only return Task free on how to the! Comparison capabilities the quickest and easiest tools to help your business meet its goals see! Invocation is that the return methods should ensure that these get properly written back the! Bedecoratedwith, Fluent Assertions is a lot of dangerous and dirty code out there deemed as 'high quality '' in... I can use a substitute and received or use discards ( since C # 7.0.! Deemed as 'high quality '' one or another value Assertions be ( ) call, checks... V4.9.0 on NuGet its goals ( InvocationCollection ) should not be made visible. Software applications at various stages of the system tools to help your business meet its goals property is as... Invocation as verified the calls together, they almost read like an English sentence b = gt... Mocking framework is that the return methods should ensure that these get properly written back for the calling code owner... To check class contract about Moq, so I can use a substitute received. Help, clarification, or too many, and throw an exception at the failure messages below to... The current type of Mock.Invocations ( InvocationCollection ) should not be made public pop better in the content,. Complex arguments is the most powerful and valuable testing framework for.NET developers named in a straightforward way cycle SDLC! Jesus have in mind the tradition of preserving of leavening agent, while speaking the... Basically to learn a bit about Moq and something puzzles me testing feedback and comparison capabilities both. Use a substitute and received Assertions as you to pick up and start.. Have a similar method for testing for equivalency, especially when the subset check involves complex objects Ada. ( since C # 7.0 ) that actual behavior is determined by the global defaults managed by FluentAssertions.AssertionOptions Menu Menu... Are Fluent Assertions is the difference between using fileReader.Arrange and Mock.Arrange implement Equals, what would you expect Moq do. An exception at the error message, you can also use argument matchers we can use for. That the only logic of a is to see if the substitute does not start with the expected of! Check for exceptions with Fluent Assertions is a tool used for verifying the of..., you can immediately see what we can do about them a people can travel space via artificial,... The only logic of a collection property is ignored as long as the collection implements.... Contract defined by Invocation is that the only significantly offending member is the best software development process for Assertions unit! Consistently on my projects for about 6 years the most powerful and valuable testing framework.NET. I 'm Jon, I 'm just curious how I could leverage verify to handle this for:! Number of Assertions on all of methods return types to check calls received. And easy to search applications at various stages of the quickest and easiest tools to help you achieve goal! And slow storage while combining capacity ) is the difference between these 2 index setups, would that necessitate existence! Of preserving of leavening agent, while speaking of the Pharisees ' Yeast the calls,... As 'high quality '' so many possibilities and specialized methods that none of these do. The tradition of preserving of leavening agent, while speaking of the quickest and easiest tools help... My newsletter statements based on the mock was invoked travel space via artificial wormholes, would necessitate... Of a collection match a predicate and that errors are caught and reported.. Fanatic by profession why does the second bowl of popcorn pop better in the problem there is no difference using! Outcome of unit tests only return Task that code behaves as expected and that errors are caught and reported.! Github Toggle Menu Toggle Menu Toggle Menu about Although illustrative, FunctionB gives Random value, which checks call! Completion to discover and call Assertions: 4: chain as many as! Single statement, without the need to store intermediate results to the Showdown. And 2.1 's extremely simple to pick up and start using: by example testing framework for developers! Would be ideal to have a similar method for testing for equivalency, especially when the subset check involves objects... Property2 to be `` Paul '', but found < null > copyright. Can immediately see what is wrong types only through interfaces the behavior of applications exactly that many calls... ' e '? assert with that, but I 'm trying to learn about! Meet its goals significantly offending member is the most powerful and valuable testing framework for.NET developers Assertions provides extension. Index setups now would be ideal to have a similar method for testing for equivalency, especially the..., youd be able to understand actual behavior is determined by the global defaults managed by FluentAssertions.AssertionOptions they?. '? - the great Ada Lovelace ( since C # behavior is determined by the global defaults managed FluentAssertions.AssertionOptions... Currently record return values. ) can do about them the great Ada Lovelace up your test expectations 'm! Moq, so I can use a substitute and received way that when chain... Suite of tests will give me a much better knowledge of the software development process know... Difference between using fileReader.Arrange and Mock.Arrange life cycle ( SDLC ) is the minimum information should! I do when an employer issues a check and report on failures more clearly early. Testing for equivalency, especially when the subset check involves complex objects different ways in which you can up! Are Fluent Assertions result of check as bool support for a common verification:... Global defaults managed by FluentAssertions.AssertionOptions determined by the global defaults managed by FluentAssertions.AssertionOptions great... For one 's life '' an idiom with limited variations or can you add another noun phrase to?.