NFluent Check only a few members of an object - c#

I am writing unit tests with Specflow 3, to test a method that query data in db and I use NFluent to have nice assertions methods.
Is there any way to smoothly test equality over a few members of an object ?
There is a method called HasFieldsWithSameValues but I found nothing in their wiki that explains how to use it thoroughly. There is a Excluding("fieldNames","etc",...) method that we can chain, but I would have to exclude over 20 public members.
Here is my feature file ( functionnal scenario, Gherkin syntax )
Scenario: TimeSheet_001_SearchForExistingTimeSheet
When I search for timesheet with id 31985
Then I get the following timesheet
| id | StatutPaid | StatutFact |
| 31985 | Paid | None |
Then I have the methods called by this code bloc :
[When(#"I search for timesheet with id (.*)")]
public void WhenJeChercheLeReleveDHeureAvecLId(int id)
{
var result = GetTimeSheetDetailQuery(id);
timeSheetContext.Result = result;
}
[Then(#"I get the following timesheet")]
public void ThenJObtiensLeReleveDHeureSuivant(Table table)
{
var sut = table.CreateInstance<TimeSheetDetail>();
Check.That(sut).HasFieldsWithSameValues<TimeSheetDetail>().Fields.IsEqualTo(timeSheetContext.Result);
}
The problem is that TimeSheetDetail is a VERY detailed object, I just need to check for 3 members for this case of test.
is there a way to write for example
//this
Check.That(sut)
.HasFieldsWithSameValues<myType>("Id","StatusPaid","StatusFact")
.IsEqualTo(timeSheetContext.Result);
//instead of this
Check.That(sut.Id).IsEQualTo(timeSheetContext.Result.Id);
Check.That(sut.StatusPaid).IsEQualTo(timeSheetContext.Result.StatusPaid);
Check.That(sut.StatusFact).IsEQualTo(timeSheetContext.Result.StatusFact);

You can achieve desired results using an anonymous type for the expected value.
Check.That(sut).HasFieldsWithSameValues(new {Id=1, StatusPaid = true, StatusFact = "Paid"});
In this way, you can focus the comparison of the fields of interests.
If you need to make many check like this, you should contemplate creating a simple dedicated type for this instead of an anonymous one.

From the sound of things, the exact functionality that you're looking for isn't directly supported by NFluent. This sounds like a good candidate for using C# extension methods, and fortunately NFluent supports extension methods.
The gist of the idea is that you can implement a method that contains the logic that you're trying to have, and this method can be directly called by NFluent in order to achieve the syntax that's closer to what you're looking for (if not exactly what you're looking for). After implementing such method, you'll be able to make a call like so:
Check.That(sut).HasFieldsWithSameValues(timeSheetContext.Result, "Id", "StatusPaid", "StatusFact");
The extension method's prototype would be something like this:
public static ICheckLink<ICheck<Object>> HasFieldsWithSameValues(this ICheck<Object> check, myType myObject, params string[] fieldsList)
Note that you may be able to get the exact syntax that you're looking for, but you'll have to do a little bit more work to figure out how to do that in the context of extension methods.
Find out more about C# extension methods here.
Find an example of how to implement NFluent extension methods here.

Related

c# Minimum required of optional parameters

So I'm trying to get a list of relation existing between two table to validate some integration test.
The database is pretty simple : Table1 <- RelationTable -> Table2
I would like to get the existing relation from a list of Table1 Ids or a list of Table2 Ids or both.
If I said that my parameter are all optional, I need to verify that both aren't null or throw a exception if so. If I force both parameter and want to allow one or the other to be null, but not both, I need to create 3 methods to handle it or force the dev who will use the method to add null parameter in the call like the code below which I think it's a ugly way to do it.
Sadly this couldn't be polymorphism because the first params is the same type...
But I would like to allow methodX to just be call method and allow the 3 possible methods into one without allowing method() with no params to be use.
protected async Task<List<Relation>> method1(List<string> table1Ids) => method3(table1Ids, null);
protected async Task<List<Relation>> method2(List<string> table2Ids) => method3(null, table2Ids);
protected async Task<List<Relation>> method3(List<string> table1Ids, List<string> table2Ids)
{
if(table1Ids == null && table2Ids == null)
throw new ArgumentNullException();
// code here
}
To be honest, I could choose if all null throw or 3 method or for bulletproof code choose both and it would work fine, but I'm searching alternate version where I can force a minimum of one parameter but don't said which one is required. I thought maybe attribute from the .Net Framework would do that for me, but I couldn't find something near that. I'm searching for something that could do that out of the box or a custom attribute to do that.
It would be code something like that. Without the if throw because the attribute would validate it.
[MinimumOptionalRequiredAttribute(1)]
protected async Task<List<Relation>> GetRelationFromListOfIds(List<string> table1Ids = null,
List<string> table2Ids = null) {
// code here
}
// Example of code that could be use
{
// Those would work
var byTable1 = GetRelationFromListOfIds(table1Ids);
var byTable2 = GetRelationFromListOfIds(table2Ids:table2Ids);
var byTable1And2 = GetRelationFromListOfIds(table1Ids, table2Ids);
// This would not be allow by the c# intellisense
var throwException = GetRelationFromListOfIds();
}
I know I'm trying to solve everything with one method instead of going with a more "normal" way. I talk about attribute, but it not necessary an attribute. I would expect the code to not compile if you try call methodEmptyParamsNotAllow(). To be honest, I'm not even sure if that is a good idea for code readability. I'm just curious about the idea. Is something similar already exist? Is the idea good? What it would look like?

How to search function using the description of this function?

I want to find necessary function by writing some key words or phrase from description of needed function. This need in cases, when I dont remember the name of function, but I know what it must do.
For examle: I want to produce sequence from two sequences. But I dont remember the function name.
Needed function called "Zip". This function has description with my wishes.
Only what I can is to search my wishes using the sources, like Google, StackOverflow and so on. I think that Visual Studio has all opportunities to find function using only its description.
But I dont know how to do this. It would be cool to find all the functions contain needed request in description and I could choose the fitting in my case.
I recommend that you do so using reflection. Add descriptions to each method like this.
Then, you can use the GetCustomAttributes class method to get a list of descriptions:
var descriptions = (DescriptionAttribute[])
nameOfClass.GetCustomAttributes(typeof(DescriptionAttribute), false);
You can iterate through your descriptions to find the correct methods to call, and you can also do this through reflection like so:
MethodInfo methodInfo = nameOfClass.GetMethod(methodName);
object result = methodInfo.Invoke(classInstance, parametersArray);
I am sure you will want to do more error checking and handling, but this at least explains how to go about doing this.
You can then search for your methods based on how the descriptions match. I'm not how you prefer to go about doing so, but I'd be happy to help.

Best way to access attributes

I am working on a framework that uses some Attribute markup. This will be used in an MVC project and will occur roughly every time I view a specific record in a view (eg /Details/5)
I was wondering if there is a better/more efficient way to do this or a good best practices example.
At any rate, I have an a couple of attributes e.g:
[Foo("someValueHere")]
String Name {get;set;}
[Bar("SomeOtherValue"]
String Address {get;set;}
What is the most efficient way/best practice to look for these attributes/Act on their values?
I am currently doing something like this:
[System.AttributeUsage(AttributeTargets.Property)]
class FooAttribute : Attribute
{
public string Target { get; set; }
public FooAttribute(string target)
{
Target = target;
}
}
And in my method where I act on these attributes(simplified example!):
public static void DoSomething(object source)
{
//is it faster if I make this a generic function and get the tpe from T?
Type sourceType = source.GetType();
//get all of the properties marked up with a foo attribute
var fooProperties = sourceType
.GetProperties()
.Where(p => p.GetCustomAttributes(typeof(FooAttribute), true)
.Any())
.ToList();
//go through each fooproperty and try to get the value set
foreach (var prop in fooProperties)
{
object value = prop.GetValue(source, null);
// do something with the value
prop.SetValue(source, my-modified-value, null);
}
}
Attribute.GetCustomAttribute and PropertyInfo/MemberInfo.GetCustomAttribute is the recommended way of getting at attribute objects.
Although, I wouldn't normally enumerate all properties with attributes; you generally want to work a particular attribute so you'd just call GetCustomAttribute directly.If you're looking for attributes on any of your properties, enumerating those properties looking for attributes based on GetCustomAttribute() the way you're doing it, is the best way to do it.
There is not really much choice when dealing with attributes - your code is ok and reasonable as is, it is also unlikley to be your main performance concern. The only immediate thing is to drop ToList call as absolutely unnecessary.
Side notes: performance related question should look approximately
"I've measured my code and portion XXX seems to be taking too much time (YYY) . The time goal for this piece of code is ZZZ. Is my way of doing XXX reasonable/where can I improve it?".
Note that in you case you are missing YYY and ZZZ time portions - so you can't really say if it is slow for your case or not. And you may want to start measurements with DB/other IO bound operations as it more likely to speed up your overall code.
After you figured that this attribute related code is main perfomance issue you can consider some sort of caching of results or even code generation of some sort (either through caching lambdas that would set necessary values or even full blown IL generation).

Integration Test for All References of a Method Invocation

So, I've been searching around on the internet for a bit, trying to see if someone has already invented the wheel here. What I want to do is write an integration test that will parse the current project, find all references to a certain method, find it's arguments, and then check the database for that argument. For example:
public interface IContentProvider
{
ContentItem GetContentFor(string descriptor);
}
public class ContentProvider : IContentProvider
{
public virtual ContentItem GetContentFor(string descriptor)
{
// Fetches Content from Database for descriptor and returns in
}
}
Any other class will get an IContentProvider injected into their constructor using IOC, such that they could write something like:
contentProvider.GetContentFor("SomeDescriptor");
contentProvider.GetContentFor("SomeOtherDescriptor");
Basically, the unit test finds all these references, find the set of text ["SomeDescriptor", "SomeOtherDescriptor"], and then I can check the database to make sure I have rows defined for those descriptors. Furthermore, the descriptors are hard coded.
I could make an enum value for all descriptors, but the enum would have thousands of possible options, and that seems like kinda a hack.
Now, this link on SO: How I can get all reference with Reflection + C# basically says it's impossible without some very advanced IL parsing. To clarify; I don't need Reflector or anything - it's just to be an automated test I can run so that if any other developers on my team check in code that calls for this content without creating the DB record, the test will fail.
Is this possible? If so, does anyone have a resource to look at or sample code to modify?
EDIT: Alternatively, perhaps a different method of doing this VS trying to find all references? The end result is I want a test to fail when the record doesnt exist.
This will be very difficult: your program may compute the value of the descriptor, which will mean your test is able to know which value are possible without executing said code.
I would suggest to change the way you program here, by using an enum type, or coding using the type safe enum pattern. This way, each and every use of a GetContentFor will be safe: the argument is part of the enum, and the languages type checker performs the check.
Your test can then easily iterate on the different enum fields, and check they are all declared in your database, very easily.
Adding a new content key requires editing the enum, but this is a small inconvenient you can live with, as it help a log ensuring all calls are safe.

Dynamic "WHERE" like queries on memory objects

What would be the best approach to allow users to define a WHERE-like constraints on objects which are defined like this:
Collection<object[]> data
Collection<string> columnNames
where object[] is a single row.
I was thinking about dynamically creating a strong-typed wrapper and just using Dynamic LINQ but maybe there is a simpler solution?
DataSet's are not really an option since the collections are rather huge (40,000+ records) and I don't want to create DataTable and populate it every time I run a query.
What kind of queries do you need to run? If it's just equality, that's relatively easy:
public static IEnumerable<object[]> WhereEqual(
this IEnumerable<object[]> source,
Collection<string> columnNames,
string column,
object value)
{
int columnIndex = columnNames.IndexOf(column);
if (columnIndex == -1)
{
throw new ArgumentException();
}
return source.Where(row => Object.Equals(row[columnIndex], value);
}
If you need something more complicated, please give us an example of what you'd like to be able to write.
If I get your point : you'd like to support users writting the where clause externally - I mean users are real users and not developers so you seek solution for the uicontrol, code where condition bridge. I just though this because you mentioned dlinq.
So if I'm correct what you want to do is really :
give the user the ability to use column names
give the ability to describe a bool function (which will serve as where criteria)
compose the query dynamically and run
For this task let me propose : Rules from the System.Workflow.Activities.Rules namespace. For rules there're several designers available not to mention the ones shipped with Visual Studio (for the web that's another question, but there're several ones for that too).I'd start with Rules without workflow then examine examples from msdn. It's a very flexible and customizable engine.
One other thing: LINQ has connection to this problem as a function returning IQueryable can defer query execution, you can previously define a query and in another part of the code one can extend the returned queryable based on the user's condition (which then can be sticked with extension methods).
When just using object, LINQ isn't really going to help you very much... is it worth the pain? And Dynamic LINQ is certainly overkill. What is the expected way of using this? I can think of a few ways of adding basic Where operations.... but I'm not sure how helpful it would be.
How about embedding something like IronPython in your project? We use that to allow users to define their own expressions (filters and otherwise) inside a sandbox.
I'm thinking about something like this:
((col1 = "abc") or (col2 = "xyz")) and (col3 = "123")
Ultimately it would be nice to have support for LIKE operator with % wildcard.
Thank you all guys - I've finally found it. It's called NQuery and it's available from CodePlex. In its documentation there is even an example which contains a binding to my very structure - list of column names + list of object[]. Plus fully functional SQL query engine.
Just perfect.

Categories

Resources