My test method looks like this:
public static List<Something> Generator() {
return A.GenerateObjects();
}
[Test, TestCaseSource(nameof(Generator))]
public void DoSomething(Something abc) {/*do something*/}
This code works very well and generates for each object in the list an unit case.
I want to include another parameter in the method like:
public void DoSomething(Something abc, string def)
I've tried it with these lines but it didn't work:
public static object[] Case =
{
new object[]
{
A.GenerateObjects(),
someStrings
}
};
Maybe iterate the list with an loop function instead of invoking the method (GenerateObjects()) directly? I also don't understand how Nunit can recognize the objects from the list directly with only TestCaseSource(nameof(Generator))
Thanks in advance!
You can return an IEnumerable of TestCaseData like this:
public static IEnumerable<TestCaseData> Generator()
{
yield return new TestCaseData(new Something { SomeValue = "Hi" }, "Foo").SetName("FirstTest");
yield return new TestCaseData(new Something { SomeValue = "Bye" }, "Bar").SetName("SecondTest");
}
[Test]
[TestCaseSource(nameof(Generator))]
public void DoSomething(Something abc, string def)
{
Console.WriteLine($"{abc.SomeValue},{def}");
}
The SetName is optional, just if you want a more meaningful name than the default one it makes up.
I also don't understand how Nunit can recognize the objects from the
list directly with only TestCaseSource(nameof(Generator))
Nunit notices the TestCaseSource attribute on the test method, and then uses reflection to invoke the "Generator" method. (Nameof is just sugar, the compiler substitutes it with the actual name when you build it). Every TestCaseData object that is returned is another test case. In my example above the tests will be run twice. FirstTest will have a Something instance where SomeValue is set to Hi and a def string of Foo. SecondTest will have a Something instance where SomeValue is set to Bye and a def string of Bar.
Your initial test takes a single argument of type Something. Apparently, A.GenerateObjects() returns some sort of IEnumerable of those objects - you don't show the detail. Because the test is a single-argument method, that works. NUnit provides a special case for single argument methods, which is very forgiving and will accept arrays of objects or of the type that is required and generate the test cases for you itself.
However, for multiple arguments, it's up to you to return a set of test cases from your method yourself. As you probably know, the arguments to a method in C# are in the form of an object[] containing the arguments, like new object[] { aSomething, "astring" }.
Assuming that you have specific strings that need to be associated with each object, it's up to you to make that association. How to do that depends on the details of what you are trying to do.
Do you have a list of strings, which you want to associate with the list of objects one for one? In that case, stop using [TestCaseSource] and use [ValueSource] or [Values] on each parameter of the test method. Apply [Sequential] to the method to cause NUnit to match up the objects and strings one for one. Here's an example...
[Test, Sequential]
public void DoSomething(
[ValueSource(typeof(A), nameof(GetObjects)] Something abc,
[Values("string1", "string2", "string3")] string def)
{/*do something*/}
This is just one way to do it. I've had to do a bunch of guessing as to what data you have readily available and what you are trying to do. If this approach doesn't work for you, please fill in the blanks a bit and I'll edit the answer.
Related
Let's say I have a method that calls another method with some parameters, something like this:
public void SomeMethod()
{
List<SomeObject> TheList = SomeQueryThatReturnsTheList();
TheList = DoSomeWorkWithList(TheList);
}
public List<SomeObject> WorkForList(List<SomeObject> TheListAsParameter)
{
foreach (SomeObject x in TheListAsParameter)
{
....
}
return TheListAsParameter;
}
As you can see, the method WorkForList returns the list it received. My question is this: if I don't return the list and rewrite the signature as public void WorkForList(List<SomeObject> TheListAsParameter) is pass by reference in c# going to mean that TheList in SomeMethod is going to be updated with the work that's done in the WorkForList method? If so, will the following code work the same:
public void SomeMethod()
{
List<SomeObject> TheList = SomeQueryThatReturnsTheList();
DoSomeWorkWithList(TheList);
}
public void WorkForList(List<SomeObject> TheListAsParameter)
{
....
}
Thanks.
Well if you don't use the ref keyword, its address will be passed by value, meaning you will be able to change its element, but you can't initialized it or can't assign it null. for example. If in your method you do:
public void WorkForList(List<SomeObject> TheListAsParameter)
{
TheListAsParameter = null;
}
You will not see the difference in the caller.
You should see this article: Parameter passing in C# by Jon Skeet
In this case, the code will do what you want to do, BUT bear in mind two things:
C# is "pass by value" language. It passes the address of the object, so this will only work if you work with this instance, not change the instance itself. For that, you should use ref keyword, but that usually ends up with harder to read code.
returning objects vastly improves readability - what you do is considered a side-effect, a user of your method (another team member maybe) may not be aware you are modifying the list contents.
Yes, you can do that. But returning the object might be useful, for clarity, and to allow methods chaining.
For example with your first WorkForList method :
yourObject.WorkForList(list).DoSomethingWithTheReturnedList();
Yes - this should behave exactly as you've described... Surely you can just test the code you've already written?
Yes, as long as your WorkForList() method doesn't have a line like this:
TheListAsParameter = something;
then any changes you make to TheListAsParameter will be reflected in the calling method without returning it.
To speak precisely here, in this case you aren't passing a variable by reference. You are passing a reference type by value. Pass by reference involves the use of the ref keyword in C#.
As long as you don't use foreach to modify values of the list:
foreach (SomeObject x in TheListAsParameter)
{
....
}
As you are not allowed to modify the contents of a Collection you are walking through using foreach.
How would I pass a list of values into a function, where the values are already stored in a list and the function isn't the same every time?
To explain, I've got a list of several different types of custom objects (A List<object> to make this work) and I want to pass those objects into a function. However, the function isn't always the same. I could have several different functions, and, assuming that List's contents will always match the function's input variables, I want to be able to pass the list's contents into my function.
The following code is an example of what might work, but for one flaw:
List<object> myListOfVariables = new List<object>();
myListOfVariables.Add("Hello, world!");
myListOfVariables.Add(10);
void SayHelloXTimes(string helloString, int x) {
for(int i = 0;i<x;i++) {
print(helloString)
}
}
SayHelloXTimes(myListOfVariables[0], myListOfVariables[1]);
Now, since I know my list will always contain the right amount of variables in the right positions, that would work, if I only had one function. But the problem is, I need to expand this so I could take apart my list and pass it into functions with different amounts of parameters.
For other reasons, I know my list will always have the right amount of variables in the right positions, so we don't need to worry about that. I'll also know the name of the function I need to pass my values into. I suppose I could do a load of if statements depending on the length of my list, like this:
if (myListOfVariables.Length == 2) {
SayHelloXTimes(myListOfVariables[0], myListOfVariables[1]);
}
else if (myListOfVariables.Length == 3) {
SayHelloXTimesForY(myListOfVariables[0], myListOfVariables[1], myListOfVariables[2]);
}
However, this (obviously) is really clunky code and I'd like to avoid it at all costs. Is there another solution to my problem? I know this is really confusing, but I did my best to explain it. If you're still confused as to what I'm trying to do, please let me know.
And no, this is not a homework problem. ;)
I think want you want to do can be done using reflection. Look at MethodBase.Invoke Method
All you have to do is add all the parameters in the order the function expects to an object array.
class Program
{
public static void SayHelloXTimes(string helloString, int x)
{
for (int i = 0; i < x; i++)
{
Console.WriteLine(helloString);
}
}
static void Main(string[] args)
{
MethodInfo Method = typeof(Program).GetMethod("SayHelloXTimes");
Method.Invoke(null, new object[] { "foo", 3 });
Console.ReadLine();
}
}
You want params:
void SayHelloXTimes(params string[] list) {
for(int i = 0;i<list.Length;i++) {
print(list[i])
}
}
SayHelloXTimes("Hi", "Hi", "Hi"); // legal
SayHelloXTimes("Hi"); // legal
SayHelloXTimes("Hi", "Hi", "Hi", "Hi", "Hi", "Hi"); // still legal
If this were my application, I would create a parameter class to hold the list values.
You could pass the list into the class' constructor and either extract it into class-local properties (since you know the positions) or you could expose the values as readonly property directly from the list.
You can then just pass an instance of the parameter class to each of the methods and not have to worry about the number of parameters to the methods.
I made a system that creates a simple string with Function/Response format, example:
Check('Value'):ShowImage(#)|Check('Value'):OtherFunction(#)....and so on
Where Check is the name of a function, Value is the parameter, ShowImage is the name of a Response function, # is the entry paremeter (result of the previous function). The pipe splits another Function/Response pair that fires if the first Check('Value') function once "checked" were not satisfied (say, if the parameter was not accomplished the Check condition the function is invalid and hence the Response part in the first Function/Response pair is not executed, so system keep trying Functions awaiting to find the one that executes the right Response).
The way the application should work is to evaluate each rule (similar to a JavaScript eval function) and take appropriate action based on function results.
At first glance, it looks complicated, because first of all I need to cast the string to the right real C# function that will actually process the condition. Therefore, depending on the function result, decide where to point to execute my Response function.
Furthermore: This is just the kind example, because there are functions as * that represent something like: "any condition is true" what in almost all cases this function is the last in the chain (the default function).
That's my problem, I can't realize what is the easiest way to cope with this problem.
Maybe a chain of delegates? Lambdas? Anonymous stored into a structure...
Could you give me your measure/advise? Where to start?
Depending on the level of extensibility you want to have, I would say the most extensible way would be to use reflection to get method references, after you have parsed the input string.
You can start by splitting your problem into smaller subproblems.
Let's say you are aiming for something like this:
static void Main(string[] args)
{
string rules =
"Check(Morning):Say(Good morning)|" +
"Check(Afternoon):Say(Good afternoon)|" +
"Check(Evening):Say(Good night)";
// next, you need some **object instances** which will
// provide a context for your "test" and "action" methods.
// you don't want to use static methods if you
// went through the pain of defining such an architecture!
// let's say that a "Tester" object has a "Check" method,
// and an "Executor" object has a "Say" method:
var tester = new Tester("Afternoon");
var executor = new Executor();
// since I suck at regular expressions,
// I am using plain string methods to split
// the expression into tokens. You might want
// to add some validation
foreach (var rule in rules.Split('|'))
{
var result = Parse(rule, tester, executor);
if (result.TestPassed)
{
result.Execute();
break;
}
}
}
A "result" as it's used above would then have an interface like this:
public interface IResult
{
// returns true if a test is fulfilled
bool TestPassed { get; }
// executes the related action
void Execute();
}
And, if you want to delegate actual actions to some unknown methods, a reasonable way to implement it would be something like this:
public class Result : IResult
{
#region IResult Members
private readonly Func<bool> _testMethod;
public bool TestPassed
{
get { return _testMethod(); }
}
private readonly Action _actionMethod;
public void Execute()
{
_actionMethod();
}
#endregion
public Result(Func<bool> testMethod, Action actionMethod)
{
_testMethod = testMethod;
_actionMethod = actionMethod;
}
}
What's left is to use some reflection to get the actual methods out of your strings:
private static IResult Parse(string rule, object tester, object executor)
{
// split into test/action
var tokens = rule.Split(':');
// extract the method/parameter part for each expression
var test = GetMethodAndParams(tokens[0]);
var action = GetMethodAndParams(tokens[1]);
// use reflection to find actual methods
var testMethod = tester.GetType().GetMethod(test.Method);
var actionMethod = executor.GetType().GetMethod(action.Method);
// return delegates which will simply invoke these methods
return new Result
(
() => (bool)testMethod.Invoke(tester, new object[] { test.Param }),
() => actionMethod.Invoke(executor, new object[] { action.Param })
);
}
That is, more or less, your program's skeleton. You should be able to fill in the missing parts yourself, as an exercise. If you have problems, I can update the answer later.
A GetMethodAndParams method should split the input string into a Tuple (or your custom class) which contains the method name and its params as plain strings. Tester and Executor classes can also be implemented trivially.
It looks like you want a pattern along the lines of the .NET TryParse() methods. In that case, you would modify your check method to have an out parameter that is the value (represented in your example by #).
int result;
if(Check('Value', out result))
ShowImage(result);
else(Check('Value2', out result))
OtherFunction(result);
Finally I'm back here to post what I've done few weeks ago to solve this situation.
It was easy.
Regex class provide few options, one of those is "Explicit Catpure", all streams with the form (?) can be handled as strong typed parameters so, if the named group "IsNotEmptyorNull" then the function is present and it is promotable to casting using the form Enum.Parse("").
Snipet:
Regex rx = new Regex(#"(?<function>Check|BooleanOp)\('(?<param>[\w]+)'\){1}:(?<action>[\w]+){1}", RegexOptions.ExplicitCapture);
Match m;
Dictionary<FunctionArray, String> actions = new Dictionary<FunctionArray, String>();
if((m=rx.Match(strStream)).Success)
{
actions.Add((FunctionArray)Enum.Parse(typeof(FunctionArray), m.Groups["function"].value, true), m.Groups["param"].value);
}
Of course, there are lost the action part so I've improved the Dictionary stuff with an specialized Struct that can handle the functions and values as a source for decision taking.
Thanks to all. Ed.
This is one of the hardest questions I've ever had to title here on SO. :) Although the title might not make sense, hopefully the question itself will.
Let's say I have a data structure like a Dictionary<string, List<double>>, and that I have functions that then take List<double>s as a parameter:
Dictionary<string, List<double>> candy_positions = new Dictionary<string, List<double>>();
candy_positions.Add( "Godiva", new List<double> { 1.0, 2.0, 4.0 });
EatCandy( candy_positions["Godiva"]);
...
But now I have decided that I don't want to do it this way. I want to replace my Dictionary with a List<CandyPositions>, where CandyPositions looks something like this:
public class CandyPositions
{
public double Sees;
public double Godiva;
public double Lindt;
}
However, I really would like to leave EatCandy() alone. Obviously, the problem is now that my data doesn't lend itself to be passed directly into the method. Instead, I have to do something lame like:
List<CandyPositions> candy_positions = new List<CandyPositions>();
...
var positions = from x in candy_positions select x.Godiva;
EatCandy( positions.ToList());
every time I want to call the method. I'd prefer to be able to do this in a more simple way, like:
EatCandy( candy_positions.GetPositionsFor( "Godiva"));
where the parameter "Godiva" matches the property name in the CandyPositions class.
After writing this question, I've realized that it isn't really about transposing data -- that part of it can be handled by writing an extension method. The part I don't know how to do is to pass in a property name, so that the extension method can take this and associate it with a class's property. I don't want to pass in a string, either, mainly because this will open the door for all sorts of runtime errors. I know how to make this work by passing "Godiva" to my extension method. What I really want to pass in is something akin to CandyPositions.Godiva instead.
This question is probably a little confusing, so in summary, I would accept the best of two types of answers:
Is there a better way to deal with transposing data, than to use an extension method + some way of accessing a property name?
Is there a way to specify the property that I want my extension method to retrieve, other than by a string?
My current extension method looks like this:
public static List<double> GetPositions( this List<CandyPositions> positions, string candy_name)
{
return (from x in positions select x.GetType().GetProperty(candy_name).GetValue(x, null)).Cast<double>().ToList();
}
Well, you could use:
public static List<double> GetPositions(this List<CandyPositions> positions,
Func<CandyPositions, double> projection)
{
return positions.Select(projection).ToList();
}
and call it with:
EatCandy(candyPositions.GetPositions(x => x.Godiva));
On the other hand, if you can change EatCandy to accept an IEnumerable<double> instead, you don't need the extra method - you can just use:
EatCandy(candyPositions.Select(x => x.Godiva));
without writing an extra method at all.
EDIT: If you need to iterate over two sequences at once, there are two options:
If you're using .NET 4, you can use the Zip extension method.
Otherwise, you can basically write your own:
using (var iterator1 = sequence1.GetEnumerator())
using (var iterator2 = sequence2.GetEnumerator())
{
while (iterator1.MoveNext() && iterator2.MoveNext())
{
var value1 = iterator1.Current;
var value2 = iterator2.Current;
// Use the values here
}
}
I've been looking at the Moq documentation and the comments are too short for me to understand each of things it can do.
The first thing I don't get is It.IsAny<string>(). //example using string
Is there an advantage of using this over just putting some value in? I know people say to use this if you don't care about the value, but if you don't care about the value can't you just do "a" or something? This just seems like more typing.
Secondly, when would be an example be of when you would not care about the value? I thought Moq needs the value to match up stuff.
I don't get what It.Is<> is for at all or how to use it. I don't understand the example and what it is trying to show.
Next, I don't get when to use Times (and its AtMost methods and similar). Why would you limit the number of times something is set up? I have some AppConfig value that I need to use twice. Why would I want to limit it to, say, once? This would just make the test fail. Is this to stop other people from adding another one to your code or something?
I don't get how to use mock.SetupAllProperties();
What does it set up the properties with?
I don't also get why there are so many different ways to set up a property and what their differences are. The documentation has:
SetupGet(of property)
SetupGet<TProperty>
I noticed that a lot of the stuff in Moq shows () and <> - what's the difference between them and what would they look like in use?
I also don't get why they have SetupGet. Would you not use SetupSet to set a property?
SetupSet has five different ways to use it in the documentation. Plus another one called SetupProperty. So I don't understand why there are so many.
On a side note, I am wondering if variables used in lambdas are independent of other lambdas. E.g.:
mock.setup(m => m.Test);
stop.setup(m => m.Test);
Would this be ok or would there be some conflict between the variable m?
Finally, I was watching this video and I am wondering if it shows Visual Studio. His Intellisense looks different. A lightbulb pops up for him (I am happy mine does not, as it brings back painful memories of netbeans), and there are lines going from one opening brace to the closing brace and etc.
It.IsAny / It.Is
These can be useful when you're passing a new reference type within the code under test. For instance, if you had a method along the lines of:
public void CreatePerson(string name, int age) {
Person person = new Person(name, age);
_personRepository.Add(person);
}
You might want to check the add method has been called on the repository,
[Test]
public void Create_Person_Calls_Add_On_Repository () {
Mock<IPersonRepository> mockRepository = new Mock<IPersonRepository>();
PersonManager manager = new PersonManager(mockRepository.Object);
manager.CreatePerson("Bob", 12);
mockRepository.Verify(p => p.Add(It.IsAny<Person>()));
}
If you wanted to make this test more explicit you can use It.Is by supplying a predicate the person object must match,
[Test]
public void Create_Person_Calls_Add_On_Repository () {
Mock<IPersonRepository> mockRepository = new Mock<IPersonRepository>();
PersonManager manager = new PersonManager(mockRepository.Object);
manager.CreatePerson("Bob", 12);
mockRepository.Verify(pr => pr.Add(It.Is<Person>(p => p.Age == 12)));
}
This way the test will through an exception if the person object that was used to call the add method didn't have the age property set to 12.
Times
If you had a method along the lines of:-
public void PayPensionContribution(Person person) {
if (person.Age > 65 || person.Age < 18) return;
//Do some complex logic
_pensionService.Pay(500M);
}
One of the things that you might want to test is that the pay method does not get called when a person aged over 65 is passed into the method
[Test]
public void Someone_over_65_does_not_pay_a_pension_contribution() {
Mock<IPensionService> mockPensionService = new Mock<IPensionService>();
Person p = new Person("test", 66);
PensionCalculator calc = new PensionCalculator(mockPensionService.Object);
calc.PayPensionContribution(p);
mockPensionService.Verify(ps => ps.Pay(It.IsAny<decimal>()), Times.Never());
}
Similarly, it's possible to imagine situations where you're iterating over a collection and calling a method for each item in the collection and you'd like to make sure that it's been called a certain amount of times, other times you simply don't care.
SetupGet / SetupSet
What you need to be aware of with these guys is that they reflect how your code is interacting with the mock rather than how you're setting up the mock
public static void SetAuditProperties(IAuditable auditable) {
auditable.ModifiedBy = Thread.CurrentPrincipal.Identity.Name;
}
In this case, the code is setting the ModifiedBy property of the IAuditable instance while it's getting the Name property of the current instance of IPrincipal,
[Test]
public void Accesses_Name_Of_Current_Principal_When_Setting_ModifiedBy() {
Mock<IPrincipal> mockPrincipal = new Mock<IPrincipal>();
Mock<IAuditable> mockAuditable = new Mock<IAuditable>();
mockPrincipal.SetupGet(p => p.Identity.Name).Returns("test");
Thread.CurrentPrincipal = mockPrincipal.Object;
AuditManager.SetAuditProperties(mockAuditable.Object);
mockPrincipal.VerifyGet(p => p.Identity.Name);
mockAuditable.VerifySet(a => a.ModifiedBy = "test");
}
In this case, we're setting up the name property on the mock of IPrincipal so it returns "test" when the getter is called on the Name property of Identity we're not setting the property itself.
SetupProperty / SetupAllProperties
Looking at the test above if it was changed to read
[Test]
public void Accesses_Name_Of_Current_Principal_When_Setting_ModifiedBy() {
Mock<IPrincipal> mockPrincipal = new Mock<IPrincipal>();
Mock<IAuditable> mockAuditable = new Mock<IAuditable>();
mockPrincipal.SetupGet(p => p.Identity.Name).Returns("test");
var auditable = mockAuditable.Object;
Thread.CurrentPrincipal = mockPrincipal.Object;
AuditManager.SetAuditProperties(auditable);
Assert.AreEqual("test", auditable.ModifiedBy);
}
The test would fail. This is because the proxy created by Moq doesn't actually do anything in the set method of a property unless you tell it to. In effect, the mock object looks a bit like this
public class AuditableMock : IAuditable {
public string ModifiedBy { get { return null; } set { } }
}
To get the test to pass you have to tell Moq to set up the property to have the standard property behavior. You can do this by calling SetupProperty and the mock will look more like
public class AuditableMock : IAuditable {
public string ModifiedBy { get; set; }
}
and the test above would pass as the value "test" would now get stored against the mock. When mocking complex objects you might want to do this for all properties, hence the SetupAllProperties shortcut
Finally, the lightbulb in the IDE is the ReSharper plugin.
If you don't care about the exact value of a property, it's far better to use .IsAny because you are being explicit about the fact that the exact value is not important. If you hardcode it as "abc", then it is not clear if your code you are testing depends on starting with "a" or ending with "c" or being 3 chars long, etc. etc.