Generate code for creating an object with current values - c#

I have this scenario, which I think must be pretty common:
class Parameter
{
public int someInt;
private decimal someDecimal;
public SubParameter subParameter;
}
class SubParameter
{
public string someString { get; set; }
}
I have a breakpoint at a call to a method that takes a Parameter as a parameter. I want to write a unit test where I call this method with the same exact value (a copy of the Parameter object "tree").
It is very tedious in this case to write the many lines declaring and initializing all the fields and properties of the class, which themselves might be non-primitive etc.
It would be nice if I could just right-click on the parameter variable and then have code auto-generated to create such an object.
So if at my breakpoint, my Parameter object has the value
Parameter parameter = new Parameter
{
someInt = 42,
someDecimal = 42.42m,
subParameter = new SubParameter { someString = "42" }
};
well, then that code would be generated. I could then use the generated code for my unit test.
Does such a thing exist?
Edit:
I guess I have been unclear. I know perfectly well how to write the code myself by hand.
What I want is that when I am hitting a breakpoint and watching a complex variable (or any variable for that matter), I want to be able to say: Generate code for me that creates a clone of this variable. I would use the generated code for my unit test.
Does such a tool exist?

Just create a helper method to create the parameter for you:
public void CreateParameter()
{
return new Parameter
{
someInt = 42,
someDecimal = 42.42m,
subParameter = new SubParameter { someString = "42" }
};
}
Sample use
[TestMethod]
public void MyTest()
{
SomeClass.MethodBeingTested(CreateParameter());
}
If you want to have a specific parameter value then modify the returned parameter or provide an overload which allows you to supply that value:
[TestMethod]
public void MyTest()
{
Parameter parameter = CreateParameter();
parameter.someInt = 23;
SomeClass.MethodBeingTested(parameter);
}
I usually have my CreateParameter populate the parameter with random values to reduce the possibility that the unit test happens to pass "by chance" for certain values, but will fail for others.

You can use TestInitialize for initialize test methods:
[TestClass]
public class UnitTest1
{
Parameter _parameter = null;
[TestInitialize]
public void Initialize()
{
_parameter = new Parameter
{
someInt = 42,
someDecimal = 42.42m,
subParameter = new SubParameter { someString = "42" }
};
}
[TestCleanup]
public void Cleanup()
{
_parameter = null;
}
[TestMethod]
public void MyTest1()
{
// test _parameter
}
[TestMethod]
public void MyTest2()
{
// test _parameter
}
}

Related

Extension method not setting value

I have a product class that looks something like this -
public class Product
{
public int ProductId { get; set; }
public string Name { get; set; }
}
I have an extension class that looks like this
public static class ProductExtension
{
public static void FixProduct(this Product product)
{
product = new Product(){Name = product.Name.ToUpper()};
//product.Name is now UPPERCASE
}
}
In my Main method I have -
static void Main(string[] args)
{
Product p = new Product() {ProductId = 1, Name = "steve"};
p.FixProduct();
System.Console.WriteLine(p.Name);
}
This prints "steve" and not what I wanted it to print: "STEVE".
Why doesn't the assignment in the extension method work?
I suggest a small change to follow a fluent interface pattern. Instead of void, return the new product instead. Don't use ref, that is weird.
public static class ProductExtension
{
public static Product FixProduct(this Product input)
{
return new Product
{
Name = input.Name.ToUpper(),
Id = input.Id
}
//product.Name is now UPPERCASE
}
}
Then use it like this:
static void Main(string[] args)
{
var p = new Product()
{
ProductId = 1,
Name = "steve"
}
.FixProduct();
System.Console.WriteLine(p.Name);
}
A neat advantage of this approach is (if you think you will need it) you can support several product classes while preserving their precise type, e.g.:
public static class ProductExtension
{
public static T FixProduct<T>(this T input) where T: Product, new
{
return new T
{
Name = input.Name.ToUpper(),
Id = input.Id
}
}
}
Now you could use it on any derived product class while keeping exactly the same syntax.
class DeluxeProduct : Product
{ }
static void Main()
{
var p = new DeluxeProduct
{
Id = 1,
Name = "Steve"
}
.FixProduct();
Console.WriteLine(p.GetType().Name)); //outputs "DeluxeProduct"
}
Now on the other hand, if all you want to do is "fix" the product's name, you could just wrap it in a property.
class Product
{
private string _name;
public int Id { get; set; }
public string Name
{
get { return _name; }
set { _name = value.ToUpper(); } //Automatically "fix" it the moment you set it
}
}
...and then you don't need an extension method at all.
Extension methods cannot be used that way. In your method you create a new instance of Product and then assign it to product which is a local reference to the passed object, and not the original reference p.
When you first enter the function what you have is two references referencing the same object in memory.
Then just before exiting the method you have two objects, one referred by each reference, with the product reference, referencing a local variable being cleaned by the GC at the end of the method call.
Solutions:
To correct this and have it closest to what you were trying to do,
change your method to get a ref parameter:
public static void FixProduct(ref Product product)
{
product = new Product() { Name = product.Name.ToUpper() };
//product.Name is now UPPERCASE
}
and then:
ProductExtension.FixProduct(ref p);
I believe a better approach all together will be (by having it a
member function or an extension method) to update the object instead
of instantiating a new one:
public static void FixProduct(this Product product)
{
product.Name = product.Name.ToUpper();
}
In your extension method, you are assigning a new Product to the variable product. This doesn't end up affecting the original referenced Product.
Modify the method to the one below to set the name on the original passed in object.
public static void FixProduct(this Product product)
{
product.Name = product.Name.ToUpper();
}
Parameters are passed by value unless they are ref or out. this doesn't change that. You can understand this syntactically because ref and out require a variable reference; otherwise only an expression is required.
Unfortunately, you can't combine this with ref or out.
You can change the value of any parameter variable, though, except in the case of ref or out, it's best avoided or limited to quick touch-ups to the passed-in value that simplify later algorithmic code.
A method is permitted to assign new values to a value parameter. Such
assignments only affect the local storage location represented by the
value parameter—they have no effect on the actual argument given in
the method invocation.
— C# Language Specification
So, the assignment does work, just not in the ref or out way.

c# restrict methods to other methods

I have a class that contains several methods eg.:
class mySqlTool{
private string _values, _table, _condition, _result;
public mySqlTool Select(string values = null){
//this is REQUIRED
_values = string.Format("select {0} ", values);
return this;
}
public mySqlTool Update(string table){
//this is REQUIRED
_table = table;
return this;
}
public mySqlTool Set(string name, String value){
//this is REQUIRED
//handle name and value
return this;
}
public mySqlTool From(string table = null){
//this is REQUIRED
_table = table;
return this;
}
public mySqlTool Where(string condition = null){
//this is OPTIONAL
_condition = condition;
return this;
}
public string Execute(){
//this is REQUIRED
//this is samplecode, of course here is checked if its select or update
//but to keep it short i erased it
statement = string.Format("{0} {1}", _values, _table);
if (!string.IsNullOrEmpty(_condition))
{
statement += string.Format(" where {0}", _condition);
}
//do some with statemen and fill result
return _result;
}
}
now I use this in this chaining way:
MySqlTool t = new MySqlTool();
string result = t.Select("a,b,c").From("x").Where("foo=bar").Execute();
My VS provides me with available methods when I hit DOT (.).
My problem is, I want to denie to use some methods before other methods have been used eg:
MySqlTool.Where().Select().From().Execute();
In this case .C() should not be callable befor .A() was called. So to clarify whats allowed and whats not, here a small list
//Allowed
t.Select().From().Execute();
t.Select().From().Where().Execute();
t.Update().Set().Set().Set().Where().Where().Where().Execute();
//not Allowed
t.Select().Where().Execute();
t.Select().Select().Select().From().Execute();
t.From()...
t.Where()...
t.Execute()....
I read some about interfaces and also about state but I'm not sure if this is what im searching for.
So my question:
Is this what I want even possible?
If yes, how is this technique called?
General description - see end for specific comments
Is this what I want even possible?
Not within the same class, no. How would the compiler know what you'd already called? (Imagine you had a method with a parameter of type Test - what methods should be available to call on that?) The type system decides what's valid and what's not - so if there are different sets of valid operations, that suggests different types.
What you can do is have different types representing the different states, which will only include the appropriate methods for state transitions. So you could have something like this:
class Test0 // Initial state
{
public Test1 A() { ... }
}
class Test1 // After calling A
{
public Test2 B() { ... }
}
class Test2 // After calling B
{
// This returns the same type, so you can call B multiple times
public Test2 B() { ... }
// This returns the same type, so you can call C multiple times
public Test2 C() { ... }
public string DoSomething() { ... }
}
Then you can use:
Test0 t = new Test0();
string x1 = t.A().B().DoSome();
string x2 = t.A().B().C().DoSome();
string x3 = t.A().B().B().B().C().C().C().DoSome();
... but your invalid cases wouldn't compile.
It works, but it's pretty ugly. Without knowing what the methods are meant to achieve, it's hard to suggest anything else - but in many cases a single method with optional parameters may be better, or possibly a builder pattern.
An alternative is to use a single class and validate the calls at execution time instead, of at compile time. That's less helpful when coding, but avoids having a huge mess of types.
Yet another alternative would be to have a single class - and create a single instance - but use interfaces to represent the state. Your class would implement all the interfaces, so it could still just return this:
interface IStart
{
IMiddle A();
}
interface IMiddle
{
IFinal B();
}
interface IFinal
{
IFinal B();
IFinal C();
string DoSomething();
}
class Test : IStart, IMiddle, IFinal
{
public IMiddle A(string x = null) { return this; }
public IFinal B(string x = null) { return this; }
public IFinal C(string x = null) { return this; }
public string DoSomethign { ... }
}
Then you'd have:
IStart t = new Test();
string x1 = t.A().B().DoSome();
string x2 = t.A().B().C().DoSome();
string x3 = t.A().B().B().B().C().C().C().DoSome();
But this feels pretty wrong to me. I'd expect the A, B and C methods to be effectively changing state in some way - so having separate types would indicate which state is available. In the first example, a Test0 definitely doesn't have the state provided by the A call, but a Test1 does... and a Test2 instance has state provided by A and B, and possibly C.
Specific example
For the specific example given, I'd probably just make the constructor handle the required information (the table name) and use properties/indexers for the rest. I'd probably separate out a query command from updates:
SqlQuery query = new SqlQuery("table")
{
Columns = { "a", "b", "c" },
Where = { "foo=bar" } // Not sure how you're parameterizing these
};
And:
SqlUpdate update = new SqlUpdate("table")
{
// Which columns to update with which values
["a"] = 10,
["b"] = 20,
Where = { "foo=bar" } // Not sure how you're parameterizing these
};
In each case there'd be an Execute method returning the appropriate results.

GetDynamicParameters() not invoked when another parameter is specified

I'm developing a PowerShell cmdlet Get-Foo in C# that defines a dynamic parameter Bar, that should show up only when the switch parameter MySwitch is specified. It also has other parameters MyString, MyInt and MyBool.
When I run the cmdlet, the dynamic parameter Bar shows up in tab completion just fine when I specify the switch parameter MySwitch along with either MyString or MyInt but not when I use it with MyBool (or any other parameter type).
Here's the code:
namespace MyCompany.Cmdlets
{
[Cmdlet(VerbsCommon.Get, "Foo")]
public class GetFoo : PSCmdlet, IDynamicParameters
{
[Parameter]
public string MyString { get; set; }
[Parameter]
public int MyInt { get; set; }
[Parameter]
public bool MyBool { get; set; }
[Parameter]
public SwitchParameter MySwitch { get; set; }
public object GetDynamicParameters()
{
if (MySwitch.IsPresent)
{
context = new FooParameters();
return context;
}
return null;
}
private FooParameters context;
protected override void ProcessRecord() {}
}
public class FooParameters
{
[Parameter]
public string Bar { get; set; }
}
}
What am I doing wrong? How do I get the dynamic parameters to show up when specifying the MyBool parameter (or a MyObject parameter)?
When using the struct "SwitchParameter", I treat it like I do any other Boolean, for example:
if (MySwitchParameter)
{
// la la la other stuff
}
GetDynamicParameters is tricky, however, you have two options with it in terms of Return
Value: Return a object that represents your parameter OR return a
RuntimeDefinedParameterDictionary object. Think of the RuntimeDefinedParameterDictionary
as a "CodeDom-Like" way of expressing your parameter.
Here is a possible rewrite to your Get-Foo Cmdlet, with emphasis on the Dynamic Parameter:
[Cmdlet(VerbsCommon.Get, "Foo",
SupportsShouldProcess = true
)]
public class GetFooCommand : PSCmdlet, IDynamicParameters
{
// First things first: Lets try making a dictionary for our return
// value in our implementation of IDynamicParameter's
// GetDynamicParameters() method
private RuntimeDefinedParameterDictionary DynamicParameters;
[Parameter]
public string MyString { get; set; }
[Parameter]
public int MyInt { get; set; }
[Parameter]
// Booleans are not as fun as SwitchParameters, IMHO
public bool MyBool { get; set; }
// Remember that SwitchParameter is really just a boolean (sort of), so
// it will default to 'false'
[Parameter]
public SwitchParameter MySwitch { get; set; }
public object GetDynamicParameters()
{
// You only want this to run when the switch is flipped,
// so try it this way and see if it works for you
if (MySwitch)
{
// Create the dictionary. We will return this at the end because
// **** spoiler alert **** it is an object :)
var runtimeParameterDictionary = new RuntimeDefinedParameterDictionary();
// Lets make that parameter now. Your example doesn't specify any
// additional parameter attributes beyond the required "ParameterAttribute",
// so here we create an empty Attribute Collection
var runtimeParameter =
new RuntimeDefinedParameter("Bar", typeof (string), new Collection<Attribute>());
// With a new Parameter, lets add it to our dictionary.
runtimeParameterDictionary.Add("Bar", runtimeParameter);
// Because we created a field for our dictionary way up top, we can assign it like I
// illustrate below. This will enable easy, predictable results when we seek to
// extract the values from the dictionary at runtime.
DynamicParameters = runtimeParameterDictionary;
// Note: You can add as many parameters as you want this way, and that Is
// why I recommend it to you now. Coding the parameters as classes outside of the
// Cmdlet, and to some extent as embedded Classes,
// within the Cmdlet Never really worked for me, so I feel your pain/frustration.
return runtimeParameterDictionary;
}
return null; // Guess the user doesn't want that Bar afterall;
}
protected override void ProcessRecord()
{
// We obviously want to sequester everything we are doing with the dynamic
// parameters so a good-old-fashioned if.. then.. else... will suffice.
if (MySwitch)
{
// Now we are here at the precipice of this DynamicParameter cmdlet.
// Here is one way to get the value desired from the dynamic parameter.
// Simply access it like a dictionary...
var bar = DynamicParameters["Bar"].Value as string;
// The reason we can do it this way is because we assigned our
// beloved value to the local variable "DynmaicParameters"
// in the GetDynamicParameters() method. We could care less about
// the return value, because if the
// switch is flipped, "DynamicParameters" will be our new best friend, and
// it will have everything we need.
WriteWarning("Your " + bar + " has been forwarded to an automatic voice messaging system ...");
}
WriteObject("Cheers was filmed before a live studio audience...");
WriteObject(MyInvocation.BoundParameters);
}
}

How to get filled interface instance as a parameter of a method after executing the method?

I have a method that fills an instance of an interface as bellow:
private static void Caller() {
IOrder order = null;
MakeOrder(order);
//order is empty
}
private static void MakeOrder(IOrder order) {
order = new Order
{
PeriodCount = mciOrderInfo.PeriodCount,
Quantity = mciOrderInfo.Quantity,
ShoppingItemId = shoppingItem
};
}
After executing this method MakeOrder the Caller will get order = null but this method fills order as above.
I know if the type of parameter was a class Order instead of interface IOrder, it will be filled and accessible in Caller method.
What is the problem?
The simpelst way is to use return:
private static void Caller()
{
IOrder order = MakeOrder();
}
private static IOrder MakeOrder()
{
return new Order
{
PeriodCount = mciOrderInfo.PeriodCount,
Quantity = mciOrderInfo.Quantity,
ShoppingItemId = shoppingItem
};
}
Or, if for some reason you want to do otherwise, you can use ref/out:
private static void Caller()
{
IOrder order;
MakeOrder(out order);
}
private static void MakeOrder(out IOrder order)
{
order = new Order
{
PeriodCount = mciOrderInfo.PeriodCount,
Quantity = mciOrderInfo.Quantity,
ShoppingItemId = shoppingItem
};
}
ref passes the parameter by reference, which means if you modify it inside your function the caller's variable will be modified.
out is basically the same, except the caller doesn't have to initialize the variable, it's always the responsibility of the callee.
Yet another way would be to pass an instance and fill its properties:
private static void Caller()
{
IOrder order = new Order();
MakeOrder(order);
}
private static void MakeOrder(IOrder order)
{
order.PeriodCount = mciOrderInfo.PeriodCount;
order.Quantity = mciOrderInfo.Quantity;
order.ShoppingItemId = shoppingItem;
}
This works because classes (and interfaces for that matter) are reference types.
You should read this MSDN article: Passing Reference-Type Parameters.
The problem is that you're dealing with multiple variables here.
This line:
MakeOrder(order);
calls MakeOrder with a copy of the value of that variable, which currently is null. Inside MakeOrder you change the local parameter variable to a new value, but the original order variable on the outside is still null.
Perhaps you want to use a return type instead:
private static void Caller()
{
IOrder order = MakeOrder(order);
}
private static IOrder MakeOrder()
{
return new Order
{
PeriodCount = mciOrderInfo.PeriodCount,
Quantity = mciOrderInfo.Quantity,
ShoppingItemId = shoppingItem
};
}
Also note that the type of the parameter has nothing to with this, even if you changed MakeOrder to take a parameter of type Order (a class) you would still have the same problem.

How to set a property on a mock in C# and Rhinomocks?

I am having problems setting the value of a property in Rhinomocks. I need to set the initial value of the property outside the method under test and then set its value inside the method under test conditionally. Some code:
public interface IResponse
{
string ResponseText { get; set; }
}
public void ProcessResponse(IResponse response)
{
if(response.ResponseText == "Unset")
{
response.ResponseText = someService.GetResponse();//someService here is irrelvant to the question
}
}
[TestMethod]
public void ResponseValueIsSetWhenConditionIsTrueTest()
{
var mock = Mock<IResponse>.GenerateMock();
mock.Stub(x => x.ResponseText).Returns("Unset");
Processor.ProcessResponse(mock);
Assert.AreEqual("Responseval", mock.ResponseText); //Fails because the method doesn't set the value of the property.
}
I need the mock's property to have an initial value going into the Act part of the test, and allow the method under test to change that value so I can assert on it later. However mock.ResponseText is always set to "Unset", and the method never changes its value - what is going on here?
Have you tried PropertyBehavior? For example:
mock.Stub(x => x.ResponseText).PropertyBehavior();
Then in your test:
mock.ResponseText = "Unset";
Processor.ProcessResponse(mock);
Assert.AreEqual("Responseval", mock.ResponseText);
First of all, there's a difference in behavior between mocks and stubs in Rhino.Mocks. Secondly, I'm not sure what version of Rhino.Mocks you are using, but using the latest one and AAA syntax, this certainly works:
public interface IResponse
{
string ResponseText { get; set; }
}
...
[Test]
public void Test()
{
IResponse response = MockRepository.GenerateStub<IResponse>();
response.ResponseText = "value1";
Assert.AreEqual("value1", response.ResponseText);
response.ResponseText = "value2";
Assert.AreEqual("value2", response.ResponseText);
}

Categories

Resources