I have code similar to this:
public List<string> Expected = new List<string>();
public int SpecifiedID;
public DataIn(int ID, string Value)
{
Expected.Add(Value);
//if (ID == SpecifiedID)
//Expected.Clear();
//Need to add this but my tests that do something like
//CollectionAssert.AreEqual(new[] { "2", "4", "6", "8" }, logic.Expected);
//all fail as Expected is empty.
}
//Example Test
[Test]
public void NewTestFunction()
{
MyClass logic = new MyClass();
logic.SpecifiedID = 4;
logic.DataIn(1,"2");
logic.DataIn(2,"4");
logic.DataIn(3,"6");
logic.DataIn(4,"8");
//This will FAIL if Expected.Clear is added in the class.
CollectionAssert.AreEqual(new[] { "2", "4", "6", "8" }, logic.Expected);
}
This is simplified a lot however I have tests that check the validity of the Expected contents when DataIn is called. However I now have realised I have to clear Expected after every DataIn call. This has broken my tests obviously as there is nothing in it to assert against.
Any suggestions on how to keep the tests that validate the contents but also allow me to empty the collection?
The answer is simple - your code does not pass your test. I.e. it does not behave as expected (you describe expected behavior in your test). So, code should change - remove call to Expected.Clear(). Or think about what you expect from your code.
UPDATE (for case when expectations changes):
public void ShoulHaveAllDataInWhenIdIsNotSpecifiedID()
{
MyClass logic = new MyClass();
logic.SpecifiedID = 3;
logic.DataIn(1,"2");
logic.DataIn(2,"4");
CollectionAssert.AreEqual(new[] { "2", "4" }, logic.Expected);
}
[Test]
public void ShoulClearAllDataWhenSpecifiedIDPassed()
{
MyClass logic = new MyClass();
logic.SpecifiedID = 3;
logic.DataIn(1,"2");
logic.DataIn(2,"4");
logic.DataIn(3,"6");
CollectionAssert.AreEqual(new[] { }, logic.Expected);
}
Also consider doing behavior testing instead of state testing. By providing mocks to your class you can check how it interacts with them. I.e. check what data passed to your class dependency.
Initialization to known good state should be part of your test/class setup method. From your description, though, it seems like you may have too much coupling between your tests or that your tests are testing too much at one time. Each test, with appropriate set up, should be independent and ideally able to run in parallel. Typically this means that each is running against a different instance of the class under test and you don't have dependencies on global data, or at least those dependencies are read-only so you can set it once for all tests.
When the SpecifiedID is matched everything has to be cleared
This is one test. Instantiate your object. Give it a SpecifiedId of X. Call DataIn() on it with Y as a first parameter and then with X as a first parameter. Assert that Expected is empty. Simple.
when the next call is made it starts adding data to it again ready for
validation
This is another test. Instantiate your object. Give it a SpecifiedId of X. Repeatedly call DataIn() on it never using X as an ID. Assert that Expected contains the passed values. Simple.
Two requirements, two tests. Really, I can't see what's the big deal here.
Why do not just change test function. Create a new test function:
[Test]
public void NewTestFunction()
{
Data("Bla");
//Test for something
Expected.Clear();
}
If this is not what you're asking for, please clarify.
Related
So for example a List containing 5 Action<T>s A, B, C, D, and E where B calls A or C at some point within its own "Actioning".
Obviously I could do something like this (please do not get distracted by the uselessness of this example):
public static List<Action<string>> ActionList = new List<Action<string>>
{
inputString => //print reverse of string
{
Console.WriteLine(inputString.Reverse());
},
inputString => //print reverse of string if "Cat" otherwise print the string twice
{
if (inputString.Equals("Cat"))
{
ActionList[0](inputString);
}
else
{
ActionList[2](inputString);
}
},
inputString => //print the string twice
{
Console.WriteLine(inputString);
Console.WriteLine(inputString);
},
inputString => //print the string in uppercase
{
Console.WriteLine(inputString.ToUpper());
},
inputString => //print the string in lowercase
{
Console.WriteLine(inputString.ToLower());
},
};
The real thing would contain hundreds of Actions, each far more complex, many calling 10s of other Actions in different ways inside switch statements, etc.
I preferably want to have each Action wrapped into their own static class so I can keep all the code relevant to making that Action work that I've written in that class too, perhaps even some extra properties too. But of course that's still a pain because I still have to hardcode the List and add elements every time I add a new Action and even though I can make a common interface for each wrapper to implement, I cannot make it static (I understand why interfaces can't be static) despite only ever needing "static behaviour" which is an immediate red flag.
Anyone know a good way to do this?
I have something like the following code:
public class MainAppClass : BaseClass
{
public IList<Token> TokenList
{
get;
set;
}
// This is execute before any thread is created
public override void OnStart()
{
MyDataBaseContext dbcontext = new MyDataBaseContext();
this.TokenList = dbcontext.GetTokenList();
}
// After this the application will create a list of many items to be iterated
// and will create as many threads as are defined in the configuration (5 at the momment),
// then it will distribute those items among the threads for parallel processing.
// The OnProcessItem will be executed for every item and could be running on different threads
protected override void OnProcessItem(AppItem processingItem)
{
string expression = getExpressionFromItem();
expression = Utils.ReplaceTokens(processingItem, expression, this);
}
}
public class Utils
{
public static string ReplaceTokens(AppItem currentProcessingItem, string expression, MainAppClass mainAppClass)
{
Regex tokenMatchExpression = new Regex(#"\[[^+~][^$*]+?\]", RegexOptions.IgnoreCase);
Match tokenMatch = tokenMatchExpression.Match(expression)
if(tokenMatch.Success == false)
{
return expression;
}
string tokenName = tokenMatch.Value;
// This line is my principal suspect of messing in some way with the multiple threads
Token tokenDefinition = mainAppClass.TokenList.Where(x => x.Name == tokenName).First();
Regex tokenElementExpression = new Regex(tokenDefintion.Value);
MyRegexSearchResult evaluationResult = Utils.GetRegexMatches(currentProcessingItem, tokenElementExpression).FirstOrDefault();
string tokenValue = string.Empty;
if (evaluationResult != null && evaluationResult.match.Groups.Count > 1)
{
tokenValue = evaluationResult.match.Groups[1].Value;
}
else if (evaluationResult != null && evaluationResult.match.Groups.Count == 1)
{
tokenValue = evaluationResult.match.Groups[0].Value;
}
expression = expression.Replace("[" + tokenName + "]", tokenValue);
return expression;
}
}
The problem I have right now is that for some reason the value of the token replaced in the expression get confused with one from another thread, resulting in an incorrect replacement as it should be a different value, i.e:
Expression: Hello [Name]
Expected result for item 1: Hello Nick
Expected result for item 2: Hello Sally
Actual result for item 1: Hello Nick
Actual result for item 2: Hello Nick
The actual result is not always the same, sometimes is the expected one, sometimes both expressions are replaced with the value expected for the item 1, or sometimes both expressions are replaced with the value expected for the item 2.
I'm not able to find what's wrong with the code as I was expecting for all the variables within the static method to be in its own scope for every thread, but that doesn't seem to be the case.
Any help will be much appreciated!
Yeah, static objects only have one instance throughout the program - creating new threads doesn't create separate instances of those objects.
You've got a couple different ways of dealing with this.
Door #1. If the threads need to operate on different instances, you'll need to un-static the appropriate places. Give each thread its own instance of the object you need it to modify.
Door #2. Thread-safe objects (like mentioned by Fildor.) I'll admit, I'm a bit less familiar with this door, but it's probably the right approach if you can get it to work (less complexity in code is awesome)
Door #3. Lock on the object directly. One option is to, when modifying the global static, to put it inside a lock(myObject) { } . They're pretty simple and straight-foward (so much simpler than the old C/C++ days), and it'll make it so multiple modifications don't screw the object up.
Door #4. Padlock the encapsulated class. Don't allow outside callers to modify the static variable at all. Instead, they have to call global getters/setters. Then, have a private object inside the class that serves simply as a lockable object - and have the getters/setters lock that lockable object whenever they're reading/writing it.
The tokenValue that you're replacing the token with is coming from evaluationResult.
evaluationResult is based on Utils.GetRegexMatches(currentProcessingItem, tokenElementExpression).
You might want to check GetRegexMatches to see if it's using any static resources, but my best guess is that it's being passed the same currentProcessingItem value in multiple threads.
Look to the code looks like that splits up the AppItems. You may have an "access to modified closure" in there. For example:
for(int i = 0; i < appItems.Length; i++)
{
var thread = new Thread(() => {
// Since the variable `i` is shared across all of the
// iterations of this loop, `appItems[i]` is going to be
// based on the value of `i` at the time that this line
// of code is run, not at the time when the thread is created.
var appItem = appItems[i];
...
});
...
}
How can i declare a variable inside String.format and use it again like :
String.Format("{0} {1}", int t = 1, new string[] { "a", "b" }.ElementAt(t));
update
I just want to learn something new and type the code in one line.
It is not necessary in this case, but useful in others.
update
I found another solution :
int indx;
var st = String.Format("{0} {1}", (indx=1), new string[] { "a", "b" }.ElementAt(indx));
It would be good if you would share reason why you try to do it this way, and maybe tell us what are you working on.
Your code to work should look like this
int t = 1;
string[] myArray = new string[] { "a", "b" };
Console.WriteLine(string.Format("{0} {1}", t, myArray[t]));
What you are attempting to do seems to be without any sense, first of all it will not work. Doing stuff your way makes it impossible to access t and array you created and even if it worked it would be same as static string string myString = "1 b". Your way you make it impossible to manipulate these variables because they would only exist in context of that one line and would be back to their initial value when it gets executed each time.
It is not possible. Consider string.format as a method with few overloads, which takes few set of parameters as mentioned in MSDN link. Your way of calling the method does not satisfy your intent hence it would fail.
I don't understand any reason why you would try to do something like this.
I'm trying to create a simple way to test string parameters in unit tests, for most string parameters, I want to check the behaviour when the parameter is Null, Empty or consists only of whitespaces.
In most of the cases, I'm checking the parameters with string.IsNullOrWhiteSpace(), and throw an exception if it has one of those three values.
Now for unit testing, it seems I have to write, for every string parameter, three unit tests. One for null values, one for empty values and one for Whitespaces.
Imagine a method with 3 or 4 string parameters, then I need to write 9 or 12 unit tests...
Can anyone come up with a simple way to test this? Maybe using AutoFixture?
To avoid duplicating the same test multiple times you can write a parameterized test.
If you're using xUnit, you would write a so called theory. A theory means you're proving a principle, that is that a certain function behaves as expected when given different samples of the same kind of input data. For example:
[Theory]
[InlineData(null)]
[InlineData("")]
[InlineData(" ")]
public void Should_throw_argument_exception_when_input_string_is_invalid(string input)
{
Assert.Throws<ArgumentException>(() => SystemUnderTest.SomeFunction(input));
}
The xUnit runner will run this test multiple times, each time assigning the input parameter to one of the values specified in the [InlineData] attribute.
If the function being tested has more than one parameter, you might not care what values are passed to the remaining ones, as long as at least one of them is a string that's either null, empty or contains only whitespace.
In this case, you can combine parameterized tests with AutoFixture. AutoFixture is designed to give you general-purpose test data that is good enough to use in most scenarios when you don't necessarily care about what the exact values are.
In order to use it with xUnit theories, you'll need to add the AutoFixture.Xunit NuGet package (or AutoFixture.Xunit2 depending on which version you're using) to your test project and use the InlineAutoData attribute:
[Theory]
[InlineAutoData(null)]
[InlineAutoData("")]
[InlineAutoData(" ")]
public void Should_throw_argument_exception_when_the_first_input_string_is_invalid(
string input1,
string input2,
string input3)
{
Assert.Throws<ArgumentException>(() =>
SystemUnderTest.SomeFunction(input1, input2, input3));
}
Only the input1 parameter will have a specific value, while the rest will be assigned random strings by AutoFixture.
One thing to note here is that the values passed through the [InlineAutoData] attribute are assigned to the test parameters based on their position. Since we need to test the same behavior for all three parameters individually, we'll have to write three tests:
[Theory]
[InlineAutoData(null)]
[InlineAutoData("")]
[InlineAutoData(" ")]
public void Should_throw_argument_exception_when_the_second_input_string_is_invalid(
string input2,
string input1,
string input3)
{
Assert.Throws<ArgumentException>(() =>
SystemUnderTest.SomeFunction(input1, input2, input3));
}
[Theory]
[InlineAutoData(null)]
[InlineAutoData("")]
[InlineAutoData(" ")]
public void Should_throw_argument_exception_when_the_third_input_string_is_invalid(
string input3,
string input1,
string input2)
{
Assert.Throws<ArgumentException>(() =>
SystemUnderTest.SomeFunction(input1, input2, input3));
}
A word on property-based testing
I can't help but think that these kinds of test scenarios are a perfect match for property-based testing. Without going into too much detail, property-based testing is about proving a specific behavior (or "property") of a function by running it multiple times with generated input.
In other words:
Property-based tests make statements about the output of your code
based on the input, and these statements are verified for many
different possible inputs.
In your case, you could write a single test to verify that the function throws an ArgumentException whenever at least one of the arguments is either null, an empty string or a string that only contains whitespace.
In .NET, you can use a library called FsCheck to write and execute property-based tests. While the API is primarily designed to be used from F#, it can also be used from C#.
However, in this particular scenario, I think you're better off sticking with regular parameterized tests and AutoFixture to achieve the same goal. In fact, writing these tests with FsCheck and C# would end up being more verbose and wouldn't really buy you much in terms of robustness.
Update: AutoFixture.Idioms
As #RubenBartelink pointed out in the comments, there is another option. AutoFixture encapsulates common assertions in a small library called AutoFixture.Idioms. You can use it to centralize the expectations on how the string parameters are validated by a method and use them in your tests.
While I do have my reservations on this approach, I'll add it here as another possible solution for the sake of completeness:
[Theory, AutoData]
public void Should_throw_argument_exception_when_the_input_strings_are_invalid(
ValidatesTheStringArguments assertion)
{
var sut = typeof(SystemUnderTest).GetMethod("SomeMethod");
assertion.Verify(sut);
}
public class ValidatesTheStringArguments : GuardClauseAssertion
{
public ValidatesTheStringArguments(ISpecimenBuilder builder)
: base(
builder,
new CompositeBehaviorExpectation(
new NullReferenceBehaviorExpectation(),
new EmptyStringBehaviorExpectation(),
new WhitespaceOnlyStringBehaviorExpectation()))
{
}
}
public class EmptyStringBehaviorExpectation : IBehaviorExpectation
{
public void Verify(IGuardClauseCommand command)
{
if (!command.RequestedType.IsClass
&& !command.RequestedType.IsInterface)
{
return;
}
try
{
command.Execute(string.Empty);
}
catch (ArgumentException)
{
return;
}
catch (Exception e)
{
throw command.CreateException("empty", e);
}
throw command.CreateException("empty");
}
}
public class WhitespaceOnlyStringBehaviorExpectation : IBehaviorExpectation
{
public void Verify(IGuardClauseCommand command)
{
if (!command.RequestedType.IsClass
&& !command.RequestedType.IsInterface)
{
return;
}
try
{
command.Execute(" ");
}
catch (ArgumentException)
{
return;
}
catch (Exception e)
{
throw command.CreateException("whitespace", e);
}
throw command.CreateException("whitespace");
}
}
Based on the expectations expressed in NullReferenceBehaviorExpectation, EmptyStringBehaviorExpectation, and WhitespaceOnlyStringBehaviorExpectation AutoFixture will automatically attempt to invoke the method named "SomeMethod" with null, empty strings and whitespace respectively.
If the method doesn't throw the correct exception – as specified in the catch block inside the expectation classes – then AutoFixture will itself throw an exception explaining what happend. Here's an example:
An attempt was made to assign the value whitespace to the parameter
"p1" of the method "SomeMethod", and no Guard Clause prevented this.
Are you missing a Guard Clause?
You can also use AutoFixture.Idioms without parameterized tests by simply instantiating the objects yourself:
[Fact]
public void Should_throw_argument_exception_when_the_input_strings_are_invalid()
{
var assertion = new ValidatesTheStringArguments(new Fixture());
var sut = typeof(SystemUnderTest).GetMethod("SomeMethod");
assertion.Verify(sut);
}
Again at the Rhino Mocks Noob Wall
mockUI.Expect( x => x.Update( new Frame[] {Frame.MakeIncompleteFrame(1, 5)} ) );
This is the exact argument that I need to match. Via trace statements, I have verified that is the actual output as well i.e. the code behaves as intended but the test disagrees. RhinoMocks responds with
TestBowlingScorer.TestGamePresenter.TestStart:
Rhino.Mocks.Exceptions.ExpectationViolationException : IScoreObserver.Update([Frame# 1, Score = 0 Rolls [ 5, PENDING, ]]); Expected #1, Actual #0.
A Frame object contains few properties but doesn't override Equals() yet (overridden ToString() seen above). Update receives an array of Frames;
How do I setup this expectation? I see an Is.Matching constraint.. not sure how to use it or rather am concerned with the verbose nature of it.
I have a helper NUnit style custom Assert
public static void AssertFramesAreEqual(Frame[] expectedFrames, Frame[] actualFrames)
{
// loop over both collections
// compare attributes
}
#Gishu,
Yeah, that's it. I just also learned about the Arg<> static class which should allow you to do something like this:
mockUI.Expect( x => x.Update(Arg<Frame[]>
.Matches(fs=>HelperPredicates.CheckFrames ( expected, fs)) ));
There is also the Arg<>.List configuration starting point which I have not explored yet but might be even better for what you want
Verified works.. don't know if this is THE RhinoMocks way
var expectedFrames = new Frame[] { Frame.MakeIncompleteFrame(1, 5) };
mockUI.Expect( x => x.Update(null) )
.IgnoreArguments()
.Constraints( Is.Matching<Frame[]>( frames => HelperPredicates.CheckFramesMatch(expectedFrames, frames) ) );
The helper predicate is just a function that returns a boolean value - True on an exact match else false.
public static bool CheckFramesMatch(Frame[] expectedFrames, Frame[] actualFrames)
{
// return false if array lengths differ
// loop over corresponding elements
// return false if any attribute differs
// return true
}