I have a class method that looks like this:
private List<string> DataStoreContents = new List<string>(new[] { "", "", "", "" });
public void InputDataStore(int DataStore, string Data)
{
DataStoreContents[DataStore - 1] = Data;
}
I want to make sure that DataStore is >=1 and <= 4
How can I write a unit test that ensures that?
Either
Assert.IsTrue(DataStore >= 1 && DataStore <= 4);
or, if you prefer the fluent interface
Assert.That(DataStore, Is.GreaterThanOrEqualTo(1).And.LessThanOrEqualTo(4));
[EDIT - in response to you clarification above]
It sounds like you want to have some sort of barrier checking to check that the supplied values are in range.
In this case, you have a few choices:
Philip Fourie has given an answer involving code contracts.
Another simple approach is to write the barrier check yourself:
public void InputDataStore(int DataStore, string Data)
{
if (DataStore < 1 || DataStore > 4)
{
throw new ArgumentOutOfRangeException("DataStore", "Must be in the range 1-4 inc.");
}
DataStoreContents[DataStore - 1] = Data;
}
If you don't want to throw an exception, but maybe want to log it and exit cleanly:
public void InputDataStore(int DataStore, string Data)
{
if (DataStore < 1 || DataStore > 4)
{
// log something here and then return
return;
}
DataStoreContents[DataStore - 1] = Data;
}
To link back to unit testing. A unit test, for example, could be a test you write to check that when InputDataStore is called with a value that is out of range, that it throws an expcetion. Another would be that when it is called with a value in range, it doesn't throw an exception, and it updates DataStoreContents correctly.
Assert.IsTrue(DataStore >= 1 && DataStore <= 4);
Perhaps this? (should all fail until you fix)
[Test]
[TestCase(5)]
[TestCase(0)]
[TestCase(int.MaxValue)]
[TestCase(int.MinValue)]
public void InvalidIndices(int index)
{
Assert.DoesNotThrow(() => yourObj.InputDataStore(index, "don't care"));
}
or (should all pass)
[Test]
[TestCase(5)]
[TestCase(0)]
[TestCase(int.MaxValue)]
[TestCase(int.MinValue)]
public void InvalidIndices(int index)
{
Assert.Throws<IndexOutOfRangeException>(() => yourObj.InputDataStore(index, "don't care"));
}
You can also use a code contract with a lot of other benefits such a static code checking.
This means that you will be warned during 'code time' about using the method incorrectly.
public void InputDataStore(int DataStore, string Data)
{
Contract.Requires(DataStore >= 1 && DataStore <= 4);
DataStoreContents[DataStore - 1] = Data;
}
A good read here: http://devjourney.com/blog/code-contracts-part-1-introduction/
I think you cannot really "test" here.
You can insert a check, which will be executed at runtime. Said check might help but it will not be that much more helpful than the ArrayOutOfBoundsException you'd get anyway...
Also, inserting a check is not the same thing as testing.
You should look at the Callers of the InputDataStore Function.
These you can test: Create some different situations, execute the callers and check whether they pass the right value to InputDataStore.
Related
if(i<2 && i>10){
//code here will never be reached or what?
}
Just in case of an integer overflow maybe?
Edit: I wrote this not knowing c# is the language used. I've used C++ but I believe that the principle is also valid for c#.
there is no single integer that satisfies the condition
the compiler may well optimize away the body of the if condition (see here for an example on compiler explorer)
however, in the case of i being volatile it is possible that the value of i changes between the i<2 and the i>10 tests. In this case the if body can be reached.
However, though it may be theoretically possible it is highly unlikely that this was the intention.
Here's my example code
#include <iostream>
using std::cout;
void foo(int i)
{
if (i < 2 && i > 10)
{
cout << "The impossible happened in foo\n";
}
}
void bar(volatile int i)
{
if (i < 2 && i > 10)
{
cout << "The impossible happened in bar\n";
}
}
It is indeed possible for some c# (assuming c# because it's tagged... not assuming integer even if it's tagged because the right-hand comparison is still an integer, so it matches the tags! ;-) ) code to go into that if... take:
public class Foo {
public static bool operator> (Foo a, int b) {
return true;
}
public static bool operator< (Foo a, int b) {
return true;
}
}
Then:
Foo i = new Foo();
if(i<2 && i>10){
Console.WriteLine("Pass!");
}
Guess the output? Check it out here
Another way, with no extra classes or operator overloading:
private static bool odd;
public static int i { get { odd = !odd; return odd ? 1 : 11; } }
Check it out
Otherwise, it could also happen if multithreading (if the value of i changes bewtween the comparisons) unless you apply correct locking
I need to perform comparison between 2 methods in c# code,
I found the SyntaxNode.IsEquivalentTo, but in case the methods are:
public void Method1()
{
//hello
}
and
public void Method1()
{
}
the return value is : True.
is there any other way with Rslyn API to perform comparison including comments trivia??
(and in the example above to get: False??)
(The reason i'm not using regular string comparison is that i wan't that spaces and new line will not count as difference, for example:
public void Method1()
{
int i=1;
}
and
public void Method1(){
int i=1 ;
}
will be equal.
At the time of writing this, there is no built-in method to support such comparison, but it is easy to write one using syntax rewriters.
The basic idea is very simple. Write a CSharpSyntaxRewriter that will remove all the non-comment trivia from both of the compared nodes and then compare the newly created nodes by using the built in IsEquivalentTo() method.
The below code does what you are looking for. To compare two nodes (MethodDeclarationSyntax in your case) just call:
firstNode.IsEquivalentToWithCommentsPreserved(secondNode);
Here is the implementation:
public static class SyntaxNodeExtensions
{
public static bool IsEquivalentToWithCommentsPreserved(this SyntaxNode syntaxNode, SyntaxNode otherNode)
{
var triviaRemover = new NonCommentTriviaRemover();
return triviaRemover.Visit(syntaxNode)
.IsEquivalentTo(triviaRemover.Visit(otherNode));
}
private class NonCommentTriviaRemover : CSharpSyntaxRewriter
{
private static readonly SyntaxTrivia EmptyTrivia = default(SyntaxTrivia);
public override SyntaxTrivia VisitTrivia(SyntaxTrivia trivia)
{
return trivia.IsKind(SyntaxKind.SingleLineCommentTrivia) ||
trivia.IsKind(SyntaxKind.MultiLineCommentTrivia)
? trivia // Preserve comments by returning the original comment trivia.
: EmptyTrivia; // Remove all other trivias.
}
}
}
Keep in mind that this code does not ignore eventual differences in trivias in comments. That means, these two versions of the methods will be considered as not being equivalent:
void Method()
{
// Some comment.
}
void Method()
{
// Some comment.
}
Let me know if you maybe need to ignore these differences as well. I can then extend the solution to cover that case as well.
I quickly tried the solution on the following non-trivial example and it worked fine:
var firstCode =
#"
// First comment.
// Second comment.
int x(int a)
{
// This is a comment.
// And this as well.
if (a == 1) // This also
{
return 0 ;
}
/*
Multi line comment.
*/if(a == -5) return -10 ;
if (a == 2)
return 0 ;
return 5;
}
";
var secondCode =
#"
// First comment.
// Second comment.
int x(int a)
{
// This is a comment.
// And this as well.
if (a
== 1) // This also
{
return 0 ;
}
/*
Multi line comment.
*/
if(a == -5) return -10 ;
if (a == 2) return 0 ;
return 5;
}
";
var firstMethod = CSharpSyntaxTree.ParseText(firstCode).GetRoot().DescendantNodes().OfType<MethodDeclarationSyntax>().First();
var secondMethod = CSharpSyntaxTree.ParseText(secondCode).GetRoot().DescendantNodes().OfType<MethodDeclarationSyntax>().First();
Console.WriteLine($"{firstMethod.IsEquivalentTo(secondMethod)}"); // Prints false.
Console.WriteLine($"{firstMethod.IsEquivalentToWithCommentsPreserved(secondMethod)}"); // Prints true.
Still, before using the code in the production it would be good to write proper unit test for it, null-checks etc. ;-)
If they need to be exactly the same, you could simply call node.ToString() on the nodes and compare the strings.
When writing preconditions for different functions with similar parameters, I want to group assertions or exceptions into a static method, rather than writing them out explicitly. For example, instead of
GetFooForUser(User user)
{
assert(null != user);
assert(user.ID > 0); // db ids always start at 1
assert(something else that defines a valid user);
...
// do some foo work
}
GetBarForUser(User user)
{
assert(null != user);
assert(user.ID > 0); // db ids always start at 1
assert(something else that defines a valid user);
...
// do some bar work
}
I would prefer to write
GetFooForUser(User user)
{
CheckUserIsValid(user);
// do some foo work
}
GetBarForUser(User user)
{
CheckUserIsValid(user);
// do some bar work
}
static CheckUserIsValid(User user)
{
assert(null != user);
assert(user.ID > 0); // db ids always start at 1
assert(something else that defines a valid user);
...
}
This feels more natural and helps cut down the code I need to write (and might even reduce the number of errors in my assertions!) but it seems to go against the idea that preconditions should help document the exact intent of a method.
Is this a common anti-pattern or are there any significant reasons not to do this?
Also, would the answer be different if I had used exceptions?
Solid Answer
It's absolutely acceptable: the .NET Source Code wraps conditions.
For instance, the StringBuilder source code has a method called VerifyClassInvariant() that it calls 18 times. The method just checks correctness.
private void VerifyClassInvariant()
{
BCLDebug.Correctness((uint)(m_ChunkOffset + m_ChunkChars.Length) >= m_ChunkOffset, "Integer Overflow");
StringBuilder currentBlock = this;
int maxCapacity = this.m_MaxCapacity;
for (; ; )
{
// All blocks have copy of the maxCapacity.
Contract.Assert(currentBlock.m_MaxCapacity == maxCapacity, "Bad maxCapacity");
Contract.Assert(currentBlock.m_ChunkChars != null, "Empty Buffer");
Contract.Assert(currentBlock.m_ChunkLength <= currentBlock.m_ChunkChars.Length, "Out of range length");
Contract.Assert(currentBlock.m_ChunkLength >= 0, "Negative length");
Contract.Assert(currentBlock.m_ChunkOffset >= 0, "Negative offset");
StringBuilder prevBlock = currentBlock.m_ChunkPrevious;
if (prevBlock == null)
{
Contract.Assert(currentBlock.m_ChunkOffset == 0, "First chunk's offset is not 0");
break;
}
// There are no gaps in the blocks.
Contract.Assert(currentBlock.m_ChunkOffset == prevBlock.m_ChunkOffset + prevBlock.m_ChunkLength, "There is a gap between chunks!");
currentBlock = prevBlock;
}
}
Dialog
Is it okay to group assertions or exceptions into a static method, rather than writing them out explicitly?
Yes. It's okay.
... it seems to go against the idea that preconditions should help document the exact intent of a method.
The name of the method that wraps the assert or Exception statements ought to communicate the wrapper's intent. Also, if the reader wants to know the specifics, then she can view the method's implementation (unless it's closed-source.)
Is this considered good or bad practice, and why?
It's good practice to wrap a set of related or commonly reused asserts in another method, because it can both improve readability and facilitate maintenance.
Is this a common anti-pattern?
The opposite, actually. You might see something like this and it's actually helpful and recommended because it communicates well.
private void IfNotValidInputForPaymentFormThenThrow(string input)
{
if(input.Length < 10 || input.Length)
{
throw new ArgumentException("Wrong length");
}
// other conditions omitted
}
It's a good idea to add ThenThrow to the end of the method so that the caller knows you're throwing. Otherwise, you might want to return a bool and let the caller decide what to do if the condition fails.
private bool IsValidInputForPaymentForm(string input)
{
if(input.Length < 10 || input.Length)
{
return true;
}
else
{
return false;
}
// other conditions omitted
}
Then the calling code can throw:
if(!IsValidInputForPaymentForm(someStringInput)
{
throw new ArgumentException();
}
Or, here is another example from the .NET source that throws an exception if some conditions fail (the ThrowHelper just throws exceptions.)
// Allow nulls for reference types and Nullable<U>,
// but not for value types.
internal static void IfNullAndNullsAreIllegalThenThrow<T>(
object value, ExceptionArgument argName)
{
// Note that default(T) is not equal to null
// for value types except when T is Nullable<U>.
if (value == null && !(default(T) == null))
ThrowHelper.ThrowArgumentNullException(argName);
}
are there any significant reasons not to do this?
What I can think of is, if the method name does not explain what you're checking, and there isn't an easy way to view the source, then you should probably avoid wrapping conditions.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
Is this way of writing IF conditions considered good coding style in Java and C# languages or not?
if (checkIfIdInFirstRange()){
//call Range1 handling method
}else if(checkIfIdInSecondRange()){
//call Range2 handling method
}else{
//call error handling method
}
I'm wondering about the method inside the IF condition itself, or would it be better to make it like:
int idInRange = getIdInRange();
//handle isInRange
I think this is fine.
Even better is if you phrase your methods like a question, or flows with the if statement
if (thisConditionIsTrue()){
// Do this
}elseif(anotherConditionIsTrue()){
// Do this instead
}elseif(isThisParameterOkay(someParameter)){
// Yeh do this
}
Some hardcore purists will even say that if you have > 3 levels of indentation, your method is too nested and should be split into smaller methods.
Doing this is IMHO good coding practice as long as the method calls don't have any side effects.
e.g.
if checkIfIdInFirstRange() this is OK:
private bool checkIfIdInFirstRange()
{
return firstRange.Contains(ID);
}
But doing this might create confusion:
private bool checkIfIdInFirstRange()
{
SomeStringProperty = "totally new value that no caller would ever expect after a call to this method";
return firstRange.Contains(ID);
}
Another possible solution - depending on the actual type of your problem at hand - could be to define an interface / base class and use polymorphism.
example:
internal abstract class A
{
public void DoSomething(int ID)
{
if(IsInRange(ID))
DoSomethingProtected(ID);
}
protected abstract bool IsInRange(int ID);
protected abstract void DoSomethingProtected(int ID);
}
internal class B : A
{
private List<int> firstRange = new List<int> { 42, 23, 5};
protected override bool IsInRange(int ID)
{
return firstRange.Contains(ID);
}
protected override void DoSomethingProtected(int ID)
{
Console.WriteLine("{0}", ID);
}
}
public class Program
{
public static void Main(string[] args)
{
B foo = new B();
foo.DoSomething(3);
foo.DoSomething(42);
}
}
CAUTION: code written without IDE to hand.
Yes. It would be much more readable if you used just a little whitespace. Bunching it up like that makes it hard to tell where things begin and end and makes else if() look like a function call.
if ( checkIfIdInFirstRange() ) {
//call Range1 handling method
}
else if ( checkIfIdInSecondRange() ) {
//call Range2 handling method
}
else {
//call error handling method
}
Making the extra variable is likely to make code harder to read since you have to define them all before the if/else stack. However, it all depends on the case. Sometimes it might be better to use a variable if you will be using an expensive function many times or if you can make the variable have a more descriptive name than the function.
Actually it is also required if you want to test multiple methods and use short-circuit evaluation.
For instance, this is safe:
if (isResourceAvailable() && isResourceValid()) {
...
}
while this may no be:
bool resAvailable = isResourceAvailable();
bool resValid = isResourceValid(); // can you call that alone?
if (resAvailable && resValid ) {
...
}
It is good style as long as the methods you call don't just do something that would be clearer if it was coded in place:
if ( a > 0 && a < 10 ) doSomething();
is better than
if ( isInRange(a, 0, 10) ) doSomething();
Eh, it's mostly up to the coder but declaring the int is a bit more readable.
It's OK to write methods in the IF condition statement. But if the method will be used more than one time, you should first use a local variable to store the return value and use the variable as the IF condition
You can aim at writing function / method names that will make the code more readable where they are used. Like:
if (idInFirstRange()){
//call Range1 handling method
}else if(idInSecondRange()){
//call Range2 handling method
}else{
Also, usual convention for functions returning bool is that they start with is - isIdInFirstRange
Lastly, try avoiding such if-else ( and switch ) ladder. Try to use Dictionaries in such cases. ( https://stackoverflow.com/questions/6506340/if-if-else-or-switch-case/6506403#6506403 )
Although this practice is not wrong or condemned by any best practices guidelines, if you have more than one call within if condition it can be a bit difficult to know which call refused to enter if statement during a debug session.
if (idInFirstRange() && idInSecondRange()){
//call Range handling method
//if didn't reach this point, who was the responsible (idInFirstRange or idInSecondRange)?
}else if(idInSecondRange()){
//call Range2 handling method
}else{
//call something else
}
I have been asked to write a testing application that needs to test a new stored procedure on multiple rows in a database, in essence I want to do something like this:
[Test]
public void TestSelect()
{
foreach(id in ids)
{
DataTable old = Database.call("old_stored_proc",id);
DataTable new_ = Database.call("new_stored_proc",id);
Assert.AreEqual(old.Rows[0]["column"],ne_.Rows[0]["column"]);
}
}
When I run this test, if 1 row doesn't match the other, the entire test fails; instead I would like to count how many times the assertion was passed and how many times it has failed. Is there a way to do this with NUnit?
I realize that NUnit might be overkill and this is a simple task without it...I just wanted to learn it. ;)
Seems like you are just Asserting the wrong thing. If you want to check all the values and then assert that there are no errors (or show the number of errors) then try this:
[Test]
public void TestSelect()
{
int errors = 0;
foreach(id in ids)
{
DataTable old = Database.call("old_stored_proc",id);
DataTable new_ = Database.call("new_stored_proc",id);
if (old.Rows[0]["column"] != new_.Rows[0]["column"])
{
errors++;
}
}
Assert.AreEqual(0, errors, "There were " + errors + " errors.");
}
1) If the id's are constant and not looked up at test run time, create a separate unit test fixture for each id. That way you will know which id's are actually failing. See here for a write up on the problems with data driven tests:
http://googletesting.blogspot.com/2008/09/tott-data-driven-traps.html
2) If you need to dynamically look up the id's making it impossible to create a fixture for each id, use akmad's suggestion with one change. Keep a list of id's where the values are not equal and add the list to the error message. It will be extremely difficult to diagnose a failing test that only states the number of errors, as you won't know what id's cause the errors.
3) I don't know how difficult it would be to do in NUnit, but in PyUnit, when we need to run tests on dynamically generated data, we dynamically create tests fixtures and attach them to the TestCase class so that we have a failed test for each piece of data that does not pass. Though I imagine this would be much more difficult without python's dynamic abilities.
I know that the question is specifically about NUnit, but interestingly enough, Gallio/MbUnit has a feature which allows to run and catch several assertions at once.
[Test]
public void MultipleTest()
{
Assert.Multiple(() =>
{
Assert.IsTrue(blabla);
Assert.AreEqual(pik, pok);
// etc.
}
}
The Assert.Multiple is catching all the failing assertions and is going to report them at the end of the test.
I would count the number of rows which do not match and then would write an assertion which will compare this number with 0 and would return the number of non matching strings in the message.
you could also use Assert.Greater for this.
P.S. In principal you should try to do one assertion per unit test. That's the gist of it.
Well you could declare a counter and then assert the value of the counter to determine pass/fail
Also, you could do the bulk of the work in the test setup, and then just create multiple tests.
I'm not clear as to why you need all the assert stmts in the same test.
Based on the objective you laid out, the entire test should fail if one row doesn't match another. Counting the number of times an assertion passes or fails gives you less information than a comparison of the outcome you expected with the outcome you actually got.
I recently had the same issue. I combined the idea of counting errors with Yann Trevin's mention of Assert.Multiple into an extension method for IEnumberable that lets me do things like:
[Test]
public void TestEvenNumbers()
{
int[] numbers = new int[] { 2, 4, 12, 22, 13, 42 };
numbers.AssertAll((num) => Assert.That((num % 2) == 0, "{0} is an odd number", num));
}
Which results in the NUnit output:
TestEvenNumbers:
5 of 6 tests passed; 0 inconclusive
FAILED: 13: 13 is an odd number
Expected: True
But was: False
Expected: 6
But was: 5
And the solution to the OP's problem would be:
[Test]
public void TestSelect()
{
ids.AssertAll(CheckStoredProcedures);
}
private void CheckStoredProcedures(Id id)
{
DataTable old = Database.call("old_stored_proc",id);
DataTable new_ = Database.call("new_stored_proc",id);
Assert.AreEqual(old.Rows[0]["column"], new_.Rows[0]["column"]);
}
Here is the extension method (note that I used "All" instead of "Multiple" for consistency with Linq terminology):
using System;
using System.Text;
using System.Collections.Generic;
using NUnit.Framework;
public static class NUnitExtensions
{
public static void AssertAll<T>(this IEnumerable<T> objects, Action<T> test)
{
int total = 0;
int passed = 0;
int failed = 0;
int inconclusive = 0;
var sb = new StringBuilder();
foreach (var obj in objects)
{
total++;
try
{
test(obj);
passed++;
}
catch (InconclusiveException assertion)
{
inconclusive++;
string message = string.Format("INCONCLUSIVE: {0}: {1}", obj.ToString(), assertion.Message);
Console.WriteLine(message);
sb.AppendLine(message);
}
catch (AssertionException assertion)
{
failed++;
string message = string.Format("FAILED: {0}: {1}", obj.ToString(), assertion.Message);
Console.WriteLine(message);
sb.AppendLine(message);
}
}
if (passed != total)
{
string details = sb.ToString();
string message = string.Format("{0} of {1} tests passed; {2} inconclusive\n{3}", passed, total, inconclusive, details);
if (failed == 0)
{
Assert.Inconclusive(message);
}
else
{
Assert.AreEqual(total, passed, message);
}
}
}
}
You can use [TestCase()] attribute if a simple hard coded list of IDs.
[Test]
[TestCase(1234)]
[TestCase(5678)]
[TestCase(7654)]
public void TestSelect(int id)
{
DataTable old = Database.call("old_stored_proc", id);
DataTable new_ = Database.call("new_stored_proc", id);
Assert.AreEqual(old.Rows[0]["column"], new_.Rows[0]["column"]);
}
This will generate three separate tests for each ID and whatever nunit test runner you use will display pass/fail counts.
If need to generate a dynamic list of IDs then recommend using [TestCaseSource()] attribute.