I'm trying to come up with a Resharper pattern to apply to sequential Shouldly asserts.
For instance, I have these checks:
field1.ShouldNotBeNull();
field2.ShouldBe(expectedField2Value);
And in this case, it should be replaced with:
this.ShouldSatisflyAllConditions(
() => field1.ShouldNotBeNull(),
() => field2.ShouldBe(expectedField2Value));
And there's no problem if this was the only case, but the thing is that there are a lot of different possibilities that aren't covered in the patterns I managed so far. What I'm trying to do is to get to the point where anytime I get two or more sequential checks of any kind (ShouldBeNull, ShouldNotBeNull, ShouldContain, etc) I'd be warned to put all of those inside a ShouldSatisfyAllConditions block, since if I keep it as individual asserts, the tests will stop running as soon as one failed, instead of giving me a list of failures in the latter case.
The problems I'm facing are:
I've been unable to use any field name in the pattern. When I select
and "Search with Pattern", I just get the names of those specific
fields, not applicable to the whole project.
EDIT: My mistake. The pattern I tried is applied anytime two fields with any name are asserted to not null.
I've been unable to apply this with any of the Shouldly asserts and I have to put it as a case-by-case (such as the example above). I only get specific patterns instead of a more generic one.
Besides the very specific cases, I can't apply this for anytime there's two or more cases. I have to select each pattern, 2 lines, 3 lines and so on.
I'm using VS 17 Enterprise and JetBrains ReSharper Ultimate 2019.2.2.
This:
$field1$.ShouldNotBeNull();
$field2$.ShouldNotBeNull();
Replaced with this:
this.ShouldSatisfyAllConditions(
() => $pageStyleProperty$.ShouldNotBeNull(),
() => $_editorObject$.ShouldNotBeNull());
If you really want to do this you can with a params Action[]
public void ShouldSatisfyAllConditions(params Action[] assertions)
{
foreach (var assertion in assertions)
{
assertion?.Invoke();
}
}
Related
I'm fairly new at functional programming, and am trying to work within a very imperative code base, so I'm trying to write code that's mostly FP, but can't be fully.
I have to write an override for the following method...
protected override string CreateEntity(XElement xe)
...where xe contains two pieces of data needed for a database update. The method needs to validate the contents of xe, then do the update, returning "" on success or a pipe-delimited list of errors if not.
I took a cue from the credit card validation sample in the language-ext tests, and wrote some helper methods like the following (implementation very similar to the sample, so omitted)...
private Validation<string, int> ValidateRegionID(XElement xe)
In the sample, he used Apply on a collection of these, which returned a Validation that was the new credit card object if all went OK, or an Error if not. In my case, I don't have anything to return if all went well (as I'm doing a database update, not creating a new object), so got as far as this...
Validation<string, Unit> validation = (ValidateRegionID(xe), ValidateClinAppsID(xe))
.Apply((regionID, clinAppsID) =>
{
// Do the database update (yes, impure code)...
return Unit.Default;
});
I don't know if this is the best way to do it, so any suggestions would be welcome.
My bigger problem is what to do next. The following works, but doesn't look very elegant or FP to me...
return validation.IsFail
? string.Join("|", validation.FailAsEnumerable())
: "";
Is there a better way of doing this?
The last part of your code (formatting errors) could be done like this:
[Fact]
void Test()
{
Validation<string, Unit> resultFromDatabase = Fail<string, Unit>("error");
var showError1 = string.Join("|", resultFromDatabase.FailToSeq()); // use the fact that FailToSeq() will return empty seq for success
var showError2 = string.Join("|", resultFromDatabase.IfSuccess(Seq<string>())); // explicitly supply a value of the error type (Seq<string>) for success case
var showError3 = resultFromDatabase.Match(_ => "", errors => string.Join("|", errors)); // only call string.Join for errors
}
Take the variant you like most. If you want to have clean code / don't rely on FailToSeq() implementation working for both cases you should explicitly handle both cases using Match or IfSuccess/IfFail.
If you want to improve your overall design (avoiding impure code), you probably will have to change some fundamental things. One (very FP) option is to use a Free Monad and there was progress in LanguageExt to make that easier, but it's probably a big step to convert a traditional OO code base. See:
https://github.com/louthy/language-ext/releases/tag/3.4.11 (Free Monad using CodeGen)
https://github.com/louthy/language-ext/wiki/Thinking-Functionally:-Application-Architecture
You can simply throw an exception in case of validation failures.
Whoever will call your code later can apply exception handling over it.
The other option is to send Error codes instead of messages. The callee, in this case, can have each error code translation to a particular error.
I would like to do a very simple test for the Constructor of my class,
[Test]
public void InitLensShadingPluginTest()
{
_lensShadingStory.WithScenario("Init Lens Shading plug-in")
.Given(InitLensShadingPlugin)
.When(Nothing)
.Then(PluginIsCreated)
.Execute();
}
this can be in Given or When it... I think it should be in When() but it doesn't really matter.
private void InitLensShadingPlugin()
{
_plugin = new LSCPlugin(_imagesDatabaseProvider, n_iExternalToolImageViewerControl);
}
Since the Constructor is the one being tested, I do not have anything to do inside the When() statement,
And in Then() I assert about the plugin creation.
private void PluginIsCreated()
{
Assert.NotNull(_plugin);
}
my question is about StoryQ, since I do not want to do anything inside When()
i tried to use When(()=>{}) however this is not supported by storyQ,
this means I need to implement something like
private void Nothing()
{
}
and call When(Nothing)
is there a better practice?
It's strange that StoryQ doesn't support missing steps; your scenario is actually pretty typical of other examples I've used of starting applications, games etc. up:
Given the chess program is running
Then the pieces should be in the starting positions
for instance. So your desire to use a condition followed by an outcome is perfectly valid.
Looking at StoryQ's API, it doesn't look as if it supports these empty steps. You could always make your own method and call both the Given and When steps inside it, returning the operation from the When:
.GivenIStartedWith(InitLensShadingPlugin)
.Then(PluginIsCreated)
If that seems too clunky, I'd do as you suggested and move the Given to a When, initializing the Given with an empty method with a more meaningful name instead:
Given(NothingIsInitializedYet)
.When(InitLensShadingPlugin)
.Then(PluginIsCreated)
Either of these will solve your problem.
However, if all you're testing is a class, rather than an entire application, using StoryQ is probably overkill. The natural-language BDD frameworks like StoryQ, Cucumber, JBehave etc. are intended to help business and development teams collaborate in their exploration of requirements. They incur significant setup and maintenance overhead, so if the audience of your class-level scenarios / examples is technical, there may be an easier way.
For class-level examples of behaviour I would just go with a plain unit testing tool like NUnit or MSpec. I like using NUnit and putting my "Given / When / Then" in comments:
// Given I initialized the lens shading plugin on startup
_plugin = new LSCPlugin(_imagesDatabaseProvider, n_iExternalToolImageViewerControl);
// Then the plugin should have been created
Assert.NotNull(_plugin);
Steps at a class level aren't reused in the same way they are in full-system scenarios, because classes have much smaller, more encapsulated responsibilities; and developers benefit from reading the code rather than having it hidden away in the step definitions.
Your Given/When/Then comments here might still echo scenarios at a higher level, if the class is directly driving the functionality that the user sees.
Normally for full-system scenarios we would derive the steps from conversations with the "3 amigos":
a business representative (PO, SME, someone who has a problem to be solved)
a tester (who spots scenarios we might otherwise miss)
the dev (who's going to solve the problem).
There might be a pair of devs. UI designers can get involved if they want to. Matt Wynne says it's "3 amigos, where 3 is any number between 3 and 7". The best time to have the conversations is right before the devs pick up the work to begin coding it.
However, if you're working on your own, whether it's a toy or a real application, you might benefit just from having imaginary conversations. I use a pixie called Thistle for mine.
I know the title is a little too broad, but I'd like to know how to avoid (if possible) this piece of code I've just coded on a solution of ours.
The problem started when this code resulted in not enough log information:
...
var users = [someRemotingProxy].GetUsers([someCriteria]);
try
{
var user = users.Single();
}
catch (InvalidOperationException)
{
logger.WarnFormat("Either there are no users corresponding to the search or there are multiple users matching the same criteria.");
return;
}
...
We have a business logic in a module of ours that needs there to be a single 'User' that matches some criteria. It turned out that, when problems started showing up, this little 'inconclusive' information was not enough for us to properly know what happened, so I coded this method:
private User GetMappedUser([searchCriteria])
{
var users = [remotingProxy]
.GetUsers([searchCriteria])
.ToList();
switch (users.Count())
{
case 0:
log.Warn("No user exists with [searchCriteria]");
return null;
case 1:
return users.Single();
default:
log.WarnFormat("{0} users [{1}] have been found"
users.Count(),
String.Join(", ", users);
return null;
}
And then called it from the main code like this:
...
var user = GetMappedUser([searchCriteria]);
if (user == null) return;
...
The first odd thing I see there is the switch statement over the .Count() on the list. This seems very strange at first, but somehow ended up being the cleaner solution. I tried to avoid exceptions here because these conditions are quite normal, and I've heard that it is bad to try and use exceptions to control program flow instead of reporting actual errors. The code was throwing the InvalidOperationException from Single before, so this was more of a refactor on that end.
Is there another approach to this seemingly simple problem? It seems to be kind of a Single Responsibility Principle violation, with the logs in between the code and all that, but I fail to see a decent or elegant way out of it. It's even worse in our case because the same steps are repeated twice, once for the 'User' and then for the 'Device', like this:
Get unique user
Get unique device of unique user
For both operations, it is important to us to know exactly what happened, what users/devices were returned in case it was not unique, things like that.
#AntP hit upon the answer I like best. I think the reason you are struggling is that you actually have two problems here. The first is that the code seems to have too much responsibility. Apply this simple test: give this method a simple name that describes everything it does. If your name includes the word "and", it's doing too much. When I apply that test, I might name it "GetUsersByCriteriaAndValidateOnlyOneUserMatches()." So it is doing two things. Split it up into a lookup function that doesn't care how many users are returned, and a separate function that evaluates your business rule regarding "I can handle only one user returned".
You still have your original problem, though, and that is the switch statement seems awkward here. The strategy pattern comes to mind when looking at a switch statement, although pragmatically I'd consider it overkill in this case.
If you want to explore it, though, think about creating a base "UserSearchResponseHandler" class, and three sub classes: NoUsersReturned; MultipleUsersReturned; and OneUserReturned. It would have a factory method that would accept a list of Users and return a UserSearchResponseHandler based on the count of users (encapsulating the logic of the switch inside the factory.) Each handler method would do the right thing: log something appropriate then return null, or return a single user.
The main advantage of the Strategy pattern comes when you have multiple needs for the data it identifies. If you had switch statements buried all over your code that all depended on the count of users found by a search, then it would be very appropriate. The factory can also encapsulate substantially more complex rules, such as "user.count must = 1 AND the user[0].level must = 42 AND it must be a Tuesday in September". You can also get really fancy with a factory and use a registry, allowing for dynamic changes to the logic. Finally, the factory nicely separates the "interpreting" of the business rule from the "handling" of the rule.
But in your case, probably not so much. I'm guessing you likely have only the one occurrence of this rule, it seems pretty static, and it's already appropriately located near the point where you acquired the information it's validating. While I'd still recommend splitting out the search from the response parser, I'd probably just use the switch.
A different way to consider it would be with some Goldilocks tests. If it's truly an error condition, you could even throw:
if (users.count() < 1)
{
throw TooFewUsersReturnedError;
}
if (users.count() > 1)
{
throw TooManyUsersReturnedError;
}
return users[0]; // just right
How about something like this?
public class UserResult
{
public string Warning { get; set; }
public IEnumerable<User> Result { get; set; }
}
public UserResult GetMappedUsers(/* params */) { }
public void Whatever()
{
var users = GetMappedUsers(/* params */);
if (!String.IsNullOrEmpty(users.Warning))
log.Warn(users.Warning);
}
Switch for a List<string> Warnings if required. This treats your GetMappedUsers method more like a service that returns some data and some metadata about the result, which allows you to delegate your logging to the caller - where it belongs - so your data access code can get on with just doing its job.
Although, to be honest, in this scenario I would prefer simply to return a list of user IDs from GetMappedUsers and then use users.Count to evaluate your "cases" in the caller and log as appropriate.
I am a newbie to unit testing - I have only done basic assert tests using mere Testmethods(my last module, I created about 50 of those).
I am currently reading a book on Unit Testing, and one of the many examples in the book has me creating a new class for each single test. Below is one of the example objects created just for one test case. My question is is it ever necessary to do this? Or when should one apply this approach and when is it not necessary?
public class and_saving_an_invalid_item_type : when_working_with_the_item_type_repository
{
private Exception _result;
protected override void Establish_context()
{
base.Establish_context();
_session.Setup(s => s.Save(null)).Throws(new ArgumentNullException());
}
protected override void Because_of()
{
try
{
_itemTypeRepository.Save(null);
}
catch (Exception exception)
{
_result = exception;
}
}
[Test]
public void then_an_argument_null_exception_should_be_raised()
{
_result.ShouldBeInstanceOfType(typeof(ArgumentNullException));
}
}
Do you need to create a new class for each individual test? I would say no, you certainly do not. I don't know why the book is saying that, or if they are just doing it to help illustrate their examples.
To answer your question, I'd recommend using a class for each group of tests... but it's really a bit more complex than that, because how you define "group" is varying and dependant on what you're doing at the time.
In my experience, a set of tests is really logically structured like a document, which can contain one or more set of tests, grouped (and sometimes nested) together by some common aspect. A natural grouping for testing Object-Oriented code is to group by class, and then by method.
Here's an example
tests for class 1
tests for method 1
primary behaviour of method 1
alternate behaviour of method 1
tests for method 2
primary behaviour of method 2
alternate behaviour of method 2
Unfortunately, in C# or java (or similar languages), you've only got two levels of structure to work with (as opposed to the 3 or 4 you really actually want), and so you have to hack things to fit.
The common way this is done is to use a class to group together sets of tests, and don't group anything at the method level, as like this:
class TestsForClass1 {
void Test_method1_primary()
void Test_method1_alternate()
void Test_method2_primary()
void Test_method2_alternate()
}
If both your method 1 and method 2 all have identical setup/teardown, then this is fine, but sometimes they don't, leading to this breakdown:
class TestsForClass1_method1 {
void Test_primary()
void Test_alternate()
}
class TestsForClass1_method2 {
void Test_primary()
void Test_alternate()
}
If you have more complex requirements (let's say you have 10 tests for method_1, the first 5 have setup requirement X, the next 5 have different setup requirements), then people usually end up just making more and more class names like this:
class TestsForClass1_method1_withRequirementX { ... }
class TestsForClass1_method1_withRequirementY { ... }
This sucks, but hey - square peg, round hole, etc.
Personally, I'm a fan of using lambda-functions inside methods to give you a third level of grouping. NSpec shows one way that this can be done... we have an in-house test framework which is slightly different, it reads a bit like this:
class TestsForClass1 {
void TestsForMethod1() {
It.Should("perform it's primary function", () => {
// ....
});
It.Should("perform it's alternate function", () => {
// ....
});
}
}
This has some downsides (if the first It statement fails, the others don't run), but I consider this tradeoff worth it.)
-- The question originally read: "is it ever really necessary to create an object for each single test I want to carry out?". The answer to that is (mostly) yes, as per this explanation.
Generally, unit tests involve the interaction of two parts
The object under test. Usually this is an instance of a class or a function you've written
The environment. Usually this is whatever parameters you've passed to your function, and whatever other dependencies the object may have a reference to.
In order for unit tests to be reliable, both of these parts need to be "fresh" for each test, to ensure that the state of the system is sane and reliable.
If the thing under test is not refreshed for each test, then one function may alter the object's internal state, and cause the next test to wrongly fail
If the environment is not refreshed for each test, then one function may alter the environment (eg: set some variable in an external database or something), which may cause the next test to wrongly fail.
There are obviously many situations where this is not the case - You might for example have a pure mathematical function that only takes integers as parameters and doesn't touch any external state, and then you may not want to bother re-creating the object under test or the test environment... but generally, most things in any Object-Oriented system will need refreshing, so this is why it is "standard practice" to do so.
I'm not quite able to follow your example, but ideally any test case should be able to run independently of any other - independently from anything else, really.
I've read about this operator on a book but being that I don't use databases that much, I cannot think of any circunstance where I'd want to get a single item. I mean, I can have a set of conditions, but then I'd use First or Last, not Single. What is the difference? What is the point of having it return just a single item, and throwing an exception if there are no results or more than one? Only thing that comes to my mind would be to make sure there is really just one item.
Thanks!
This is exactly why you'd want that. Sometimes, having more than one item in the result set indicates a bug somewhere and you'd like an exception to be thrown if that is not the case.
The classic example here is when you have an id (and so expect the data to exist, uniquely, by that id):
var item = ctx.SomeTable.Single(x=>x.Id == id);
You could check SingleOrDefault if useful (to give a better error message if you get a null), but getting 2 (or more) is definitely a big problem.
The LINQ extensions are useful outside of databases as well. An actual example was to find the correct factory from a framework for a given input string. If the input string matched multiple factories, that was considered an error (or at least needed special case handling). I've also used LINQ (and single in particular) for building unit tests.
Example:
try {
IWorkspaceFactory factories[] = {
new SdeFactory(), new FGDBFactory(), new AccessFactory() };
IWorkspace workspace = factories
.Single(wf=>wf.IsWorkspace(input)).Open(input);
workspace.DoSoething();
} catch(OperationException) {
//can't remember the exact exception off the top of my head
//Catch more than one match
}