How To write TestCase nunit test for keyPairValue - tdd

I am looking for a way to pass keyValuePair into my test with TestCase
[TestCase<KeyValuePair<int,string>>(1,"XX")]
public void someTest(KeyValuePair<int,string> expectedkeyValuePairs)
{
// do some thing;
}
The answer is
[TestCase(1,"XXX")]
public void someTest(int key,string value)
{
var expectedkeyValuePairs = new KeyValuePair<int, string>(key, value);
// do some thing;
}

Simply use two separate parameters: One for key, one for value. And then create the KeyValuePair from them within your test.

Related

How to check record in c# 9 in NET 5 is immutable at runtime

Record is a new feature in c#9, Net 5
It's said
If you want the whole object to be immutable and behave like a value, then you should consider declaring it as a record
Creating a record in c#9 , NET 5:
public record Rectangle
{
public int Width { get; init; }
public int Height { get; init; }
}
Then instantiating it:
var rectangle = new Rectangle (20,30);
Trying to change the value:
rectange.Width=50; //compiler error
Compiler raise the error:
error CS8852: Init-only property or indexer 'Rectangle.Width' can only be assigned in an object initializer, or on 'this' or 'base' in an instance constructor or an 'init' accessor.
That is right and insure that the record is immutable.
Using a method like to test IsImmutable type give false, because in record there is no generated readonly properties.
How to check the record in c# 9, Net 5 is immutable at runtime or even it has init property?
A record is indeed mutable at runtime. This is intentional, is it means most serializer frameworks work without updating.
It is however possible to check if a property is initonly by checking:
public static bool IsInitOnly(PropertyInfo propertyInfo)
{
return propertyInfo?.SetMethod.ReturnParameter
.GetRequiredCustomModifiers()
.Any(x => x.FullName == _isExternalInitName)
?? false;
}
private static string _isExternalInitName =
typeof(System.Runtime.CompilerServices.IsExternalInit).FullName;
I don't think that it's possible to check for immutability at runtime.
Here's some of the generated code for your record. You can see that both properties have a public setter.
public class Rectangle : IEquatable<Rectangle>
{
[CompilerGenerated]
private readonly int <Width>k__BackingField;
[CompilerGenerated]
private readonly int <Height>k__BackingField;
protected virtual Type EqualityContract
{
[CompilerGenerated]
get
{
return typeof(Rectangle);
}
}
public int Width
{
[CompilerGenerated]
get
{
return <Width>k__BackingField;
}
[CompilerGenerated]
set
{
<Width>k__BackingField = value;
}
}
public int Height
{
[CompilerGenerated]
get
{
return <Height>k__BackingField;
}
[CompilerGenerated]
set
{
<Height>k__BackingField = value;
}
}
The following code will compile and run without errors.
var rect = new Rectangle { Height = 1, Width = 2 };
typeof(Rectangle).GetProperty("Height").SetValue(rect, 5);
Console.Write(rect.Height);
//Prints 5
At runtime the init accessor is just a regular setter. It's only at compile time that a check is made to only allow init accessor to be called during object initialization.
So I don't see any way to check at runtime that Rectangle is immutable.

Code lens not showing correct number of tests

In the VS 2013, I see number of unit tests for a method.
It works fine if I am calling the method directly from the TestMethod, but if I call sut from a helper/private method, the codelens does not seem to count that test.
I am using private method to pass different parameters to my test method and execute the test. I know I can use xls, csv or db to do that but I just want to do that in the code and make the test count.
Is there a way to make codelens count tests in this scenario?
MyClass.cs
--1/1 passing ( this is fine)
public bool MyMethbod (bool input)
{
return input
}
MyClassTest.cs
[TestMethod]
public void MyMethod_ShuoldReturnTrue
{
var returnValue = new MyClass().MyMethod(true);
Assert.IsTrue(returnValue)
}
MyClass.cs
--0/0 passing ( I am expecting codelens to show 1/1)
public bool MyMethbod (bool input)
{
return input;
}
MyClassTest.cs
[TestMethod]
public void MyMethod_ShuoldReturnTrue
{
MyMethod_ShuoldReturnTrue_Refactored(true);
}
private void MyMethod_ShuoldReturnTrue_Refactored(bool someValue)
{
var returnValue = new MyClass().MyMethod(someValue);
Assert.AreEqual(returnValue, someValue);
}

JFace TreeView not launching when Input is a String

I'm trying launch a simple JFace Tree.
It's acting really strange however. When I setInput() to be a single String, the tree opens up completely blank. However, when I set input to be a String array, it works great.
This has nothing to do with the LabelProvider or ContentProvider since these behave the same no matter what (it's a really simple experimental program).
setInput() is officially allowed to take any Object. I am confused why it will not take a String, and knowing why may help me solve my other problems in life.
Setting a single String as input:
TreeViewer treeViewerLeft = new TreeViewer(shell, SWT.SINGLE);
treeViewerLeft.setLabelProvider(new TestLabelProvider());
treeViewerLeft.setContentProvider(new TestCompareContentProvider());
treeViewerLeft.expandAll();
treeViewerLeft.setInput(new String("Stooge"));
Setting an array of Strings:
TreeViewer treeViewerLeft = new TreeViewer(shell, SWT.SINGLE);
treeViewerLeft.setLabelProvider(new TestLabelProvider());
treeViewerLeft.setContentProvider(new TestCompareContentProvider());
treeViewerLeft.expandAll();
treeViewerLeft.setInput(new String[]{"Moe", "Larry", "Curly"});
The second works, and launches a tree using the following providers:
public class TestCompareContentProvider extends ArrayContentProvider implements ITreeContentProvider {
public static int children = 0;
public Object[] getChildren(Object parentElement) {
children++;
if (children > 20){
return null;
}
return new String[] {"Moe", "Larry", "Curly"};
}
public Object getParent(Object element) {
return "Parent";
}
public boolean hasChildren(Object element) {
if (children >20){
return false;
}
return true;
}
}
and
public class TestLabelProvider extends LabelProvider {
public String getText(Object element){
return "I'm something";
}
public Image getImage(Object element){
return null;
}
}
You've inherited getElements from the ArrayContentProvider and that only works with arrays. You should override this method.
I don't think you need to extend ArrayContentProvider at all.

Caliburn Micro Communication between ViewModels

hopefully you can help me. First of all, let me explain what my problem is.
I have two ViewModels. The first one has e.g. stored information in several textboxes.
For example
private static string _tbxCfgLogfile;
public string TbxCfgLogfile
{
get { return _tbxCfgLogfile; }
set
{
_tbxCfgLogfile = value;
NotifyOfPropertyChange(() => TbxCfgLogfile);
}
}
The other ViewModel has a Button where i want to save this data from the textboxes.
It does look like this
public bool CanBtnCfgSave
{
get
{
return (new PageConfigGeneralViewModel().TbxCfgLogfile.Length > 0 [...]);
}
}
public void BtnCfgSave()
{
new Functions.Config().SaveConfig();
}
How can i let "CanBtnCfgSave" know that the condition is met or not?
My first try was
private static string _tbxCfgLogfile;
public string TbxCfgLogfile
{
get { return _tbxCfgLogfile; }
set
{
_tbxCfgLogfile = value;
NotifyOfPropertyChange(() => TbxCfgLogfile);
NotifyOfPropertyChange(() => new ViewModels.OtherViewModel.CanBtnCfgSave);
}
}
It does not work. When i do remember right, i can get the data from each ViewModel, but i cannot set nor Notify them without any effort. Is that right? Do i have to use an "Event Aggregator" to accomplish my goal or is there an alternative easier way?
Not sure what you are doing in your viewmodels - why are you instantiating viewmodels in property accessors?
What is this line doing?
return (new PageConfigGeneralViewModel().TbxCfgLogfile.Length > 0 [...]);
I can't be sure from your setup as you haven't mentioned much about the architecture, but sincce you should have an instance of each viewmodel, there must be something conducting/managing the two (or one managing the other)
If you have one managing the other and you are implementing this via concrete references, you can just pick up the fields from the other viewmodel by accessing the properties directly, and hooking the PropertyChanged event of the child to notify the parent
class ParentViewModel : PropertyChangedBase
{
ChildViewModel childVM;
public ParentViewModel()
{
// Create child VM and hook up event...
childVM = new ChildViewModel();
childVM.PropertyChanged = ChildViewModel_PropertyChanged;
}
void ChildViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
// When any properties on the child VM change, update CanSave
NotifyOfPropertyChange(() => CanSave);
}
// Look at properties on the child VM
public bool CanSave { get { return childVM.SomeProperty != string.Empty; } }
public void Save() { // do stuff }
}
class ChildViewModel : PropertyChangedBase
{
private static string _someProperty;
public string SomeProperty
{
get { return _someProperty; }
set
{
_someProperty = value;
NotifyOfPropertyChange(() => SomeProperty);
}
}
}
Of course this is a very direct way to do it - you could just create a binding to CanSave on the child VM if that works, saving the need to create the CanSave property on the parent

Expression.Default in .NET 3.5

How can I emulate Expression.Default (new in .NET 4.0) in 3.5?
Do I need to manually check the expression type and use different code for reference and value types?
This is what I'm currently doing, is there a better way?
Expression GetDefaultExpression(Type type)
{
if (type.IsValueType)
return Expression.New(type);
return Expression.Constant(null, type);
}
The way you did it is good. There is no Type.GetDefaultValue() method built in to the .NET Framework as one would expect, so the special case handling for value types is indeed necessary.
It is also possible to produce a constant expression for value types:
Expression GetDefaultExpression(Type type)
{
if (type.IsValueType)
return Expression.Constant(Activator.CreateInstance(type), type);
return Expression.Constant(null, type);
}
The advantage of this I suppose would be that the value type is only instanciated once, when the expression tree is first built, rather than every time the expression is evaluated. But this is nitpicking.
How about using an extension method?
using System;
using System.Linq.Expressions;
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
Type t = typeof(int);
Expression e = t.Default(); // <-----
Console.WriteLine(e);
t = typeof(String);
e = t.Default(); // <-----
Console.WriteLine(e);
Console.ReadLine();
}
}
public static class MyExtensions
{
public static Expression Default(this Type type)
{
if (type.IsValueType)
return Expression.New(type);
return Expression.Constant(null, type);
}
}
}

Resources