I have the following situation and any help would be appreciated.
public class Poco
{
public string SomeData { get;set; }
public string SomeMoreData { get;set; }
}
public class Worker
{
public Poco DoWork()
{
// do stuff
}
}
TESTING METHOD A.......
[Test]
public static void TestPocoIsPopulated()
{
var objUt = new Worker();
var actual = objUt.DoWork();
var expected = new Poco { SomeData = "reusltOne", SomeMoreData = "resultTwo" };
actual.ShouldBeEquivalentTo(expected);
}
This works fine. However, with larger tests of nested classes, using ShouldBeEquivalentTo() becomes cumbersome, and I'd like to be able to do this as follows...
EDIT: Also with Method A you cant do this....
var expected = new Poco { SomeData = [NOT_NULL] , SomeMoreData = "resultTwo" };
TESTING METHOD B.......
[Test]
public static void TestPocoIsPopulated()
{
var objUt = new Worker();
var actual = objUt.DoWork();
actual.SomeData.Should().Be("resultOne");
actual.SomeMoreData.Should().Be("resultTwo");
}
However, if I add a new property to Poco, then Testing Method B does not complain, and the property may not get tested. Using Method A however, the test will fail as ShouldBeEquivalentTo() will note that the new property is null
So, my question is, is there a method C as follows.
TESTING METHOD C.........
[Test]
public static void TestPocoIsPopulated()
{
var objUt = new Worker();
var actual = objUt.DoWork();
actual.SomeData.Should().Be("resultOne");
actual.SomeMoreData.Should().Be("resultTwo");
actual.Should().HaveAllPropertiesBeenTested().EqualTo(true); // <-------- is this possible?
}
The ultimate question to your answer is no, we don't support verifying whether all properties have been tested. That would require some kind of proxy generation technique that tracks access to a property. I must admit it is an interesting idea, so you could propose an enhancement on https://github.com/dennisdoomen/FluentAssertions/issues?state=open
Related
I need to change a specific property dynamically and have been using this snipplet:
var _oldMethod = typeof(TypeName).GetProperty("OldProperty", BindingFlags.Public | BindingFlags.Static).GetMethod;
var _newMethod = typeof(OwnTypeName).GetProperty("NewProperty", BindingFlags.Public | BindingFlags.Static).GetMethod;
ReplaceMethod(_oldMethod, _newMethod);
...
private static unsafe void ReplaceMethod(MethodInfo _oldMethod, MethodInfo _newMethod)
{
var _oldMethodAddress = new IntPtr((int*)_oldMethod.MethodHandle.Value.ToPointer() + 2);
var _destination = (uint*)_oldMethodAddress.ToPointer();
*destination = (uint)_newMethod.MethodHandle.GetFunctionPointer().ToInt32();
}
Unfortunately this required some decompiling with recreating the original property. What I am looking for now is a a possibility to duplicate and kind of backup the original method and dynamically replace the old method with the new one or restore the original one.
Has anyone an idea how to implement this?
Edit:
I may should have clarified my situation further:
public static class ClassName
{
public static bool Property
{
get
{
// Conditions
}
}
}
I can't access ClassName and need to force Property to false in specific situations and need to replace it to the original return value in other situations. I have been using the ReplaceMethod above mentioned but don't want to decompile and rebuild Property from scratch (instead some kind of backup of the original Property)
First of all, you are handling properties instead of methods.
One easy approach to do this is to replace your properties type by Func<> and this will keep what you're wanting to do easier.
private static void Main(string[] args)
{
var a = new A();
a.Property = Method1;
Console.WriteLine(a.Property.Invoke());
a.Property = Method2;
Console.WriteLine(a.Property.Invoke());
Func<string> oldMethod = a.Property;
Console.WriteLine(oldMethod.Invoke());
Console.ReadLine();
}
public class A
{
public Func<string> Property { get; set; }
}
private static string Method1()
{
return "Method1";
}
private static string Method2()
{
return "Method2";
}
You can change the method as many times as you want and also keep the old one in one variable.
I want to be able to store code in a database and then execute it dynamically (using Roslyn). However, I want to be able to (inject?) properties from calling code. See below:
using Roslyn.Scripting.CSharp;
using RoslynMVCTest.Interfaces;
namespace RoslynMVCTest.Services
{
public class MyService
{
private readonly IInjectedService _injectedService;
public MyService(IInjectedService injectedService)
{
_injectedService = injectedService;
}
public bool SomeMethod()
{
string codeString = #"
using RoslynMVCTest.Interfaces;
public class SomethingDoer
{
public IInjectedService InjectedService {get;set;}
public static bool DoSomething()
{
return IInjectedService.SomeOtherMethod();
}
}";
var engine = new ScriptEngine();
var session = engine.CreateSession(_injectedService);
session.AddReference(this.GetType().Assembly);
//How do I set the property in my dynamic code to _injectedService??
var result = session.Execute<bool>("SomethingDoer.DoSomething()");
return result;
}
}
}
I realize there are probably syntax and other issues here, but it's a good representation of what I want to do. Is there a way to do this?
First I'm going to answer your question matching your original code as closely as possible. Second, I'm going to show a far more concise example that might in fact be all that you're after.
You can certainly declare your type as you've done, but a few things will have to be fixed to even get it to make sense.
Your SomethingDoer class declares a non-static InjectedService property, despite the fact that you attempt to consume that property in a static method. I will assume for the sake of discussion that you intended SomethingDoer.DoSomething to be non-static as well and will thus instanatiate that class.
public static bool DoSomething()
To:
public bool DoSomething()
The "sesion" you pass to CreateSession is your actual service. To understand why this won't work, you have to understand what the argument you pass to CreateSession means and what's done with it. What the "session" means is that all the public properties of that object are available to your scripting session as raw identifiers without the need to . reference them on any target. Thus, to get your code working, I've introduced a new class (inner to the main service class for convenience) called Session:
public class Session
{
public IInjectedService InjectedService { get; set; }
}
Furthermore, I've used this new class when invoking CreateSession:
var session = engine.CreateSession(new Session { InjectedService = _injectedService });
What this means is that the property InjectedService is now available to you within your codeString.
Perhaps most importantly, your code codeString is never actually consumed by your code! You seem to have, understandably, conceived of this process as setting up a string for your code, and then imagined that you could then invoke some arbitrary method within it. On the contrary, there is only one block of code. So if you really want to declare a whole class in your script-code, you're still going to have to consume it directly within your script-code as well. This means that the final two lines of your codeString should actually look like:
var somethingDoer = new SomethingDoer { InjectedService = InjectedService };
somethingDoer.DoSomething()";
Here we're instantiating SomethingDoer (because of change 1.) and setting the service property by the implicit InjectedService value provided by the session (because of change 2.).
For completeness, here is the fully working sample code:
namespace RoslynMVCTest.Interfaces
{
public interface IInjectedService
{
bool SomeOtherMethod();
}
}
namespace RoslynMVCTest.Services
{
using RoslynMVCTest.Interfaces;
class Program
{
static void Main(string[] args)
{
Console.WriteLine(new MyService(new InjectedService()).SomeMethod());
Console.ReadLine();
}
}
class InjectedService : IInjectedService
{
public bool SomeOtherMethod()
{
return true;
}
}
public class MyService
{
private readonly IInjectedService _injectedService;
public MyService(IInjectedService injectedService)
{
_injectedService = injectedService;
}
public class Session
{
public IInjectedService InjectedService { get; set; }
}
public bool SomeMethod()
{
string codeString = #"
using RoslynMVCTest.Interfaces;
public class SomethingDoer
{
public IInjectedService InjectedService { get; set; }
public bool DoSomething()
{
return InjectedService.SomeOtherMethod();
}
}
var somethingDoer = new SomethingDoer { InjectedService = InjectedService };
somethingDoer.DoSomething()";
var engine = new ScriptEngine();
var session = engine.CreateSession(new Session { InjectedService = _injectedService });
session.AddReference(this.GetType().Assembly);
//How do I set the property in my dynamic code to _injectedService??
var result = session.Execute<bool>(codeString);
return result;
}
}
}
Alternative Approach
If all you want to do is allow your script to run some code that interacts with your service, you can see how this is actually extremely trivial given all the points made above. Thus to concisely express what might be the intent of your original code, all you'd have to do is:
var result = session.Execute<bool>("InjectedService.SomeOtherMethod()");
The code passed in here is simply the body of the service method in the long-winded first example. Quite possibly this is all you need or want.
I am new to c# MVC and I don't understand my error:
Object reference not set to an instance of an object
I have the following in my Controller:
namespace Prigmore2013_01.Tests
{
public class Exercise09Controller : Controller
{
...
public ActionResult GuessTheDigits(List<int> guesses)
{
GuessingGame theGame = this.Session["GameState"] as GuessingGame;
theGame.GuessTheHiddenDigits(guesses);
// The above is passing to the method in GuessingGame class?
return RedirectToAction("Index", theGame);
}
...
}
}
I am calling the theGame.GuessTheHiddenDigits(guesses); and passing this across to the following class:
namespace Prigmore2013_01.Models
{
public class GuessingGame
{
public GuessingGame()
{
this.Guesses = new List<Guess>();
this.Target = new List<int>();
this.guess = new List<int>();
}
public List<int> Target { get; set; }
public List<Guess> Guesses { get; set; }
public List<int> guess { get; set; }
public void GuessTheHiddenDigits(List<int> guesses)
{
// getting the guesses passed from the controller, debugging shows that
this.guess = new List<int>(guesses);
Guess m = new Guess();
m.Digits.AddRange(this.guess);
}
}
}
I have another class called Guess:
namespace Prigmore2013_01.Models
{
public class Guess
{
public Guess()
{
this.Digits = new List<int>();
}
public List<int> Digits { get; set; }
public object RightDigitRightPosition { get; set; }
public object RightDigitWrongPosition { get; set; }
}
}
The above method public void GuessTheHiddenDigits(List<int> guesses) within here needs to add a submitted guess (guesses) to the List<Guess> objects. I thought I had instantiated the method by doing this:
this.guess = new List<int>(guesses);
Guess m = new Guess();
m.Digits.AddRange(this.guess);
EDIT 1:
Found the error that has formed within the Unit test that I am running:
[TestMethod]
public void GuessTheHiddenDigitsAddsTheSubmittedGuessToTheListOfGuesses()
{
var theGame = new GuessingGame();
/* NOTE : The next line forces us to add a behaviour to the GuessingGame
* class: the GuessTheHiddenDigits() method.
* */
theGame.GuessTheHiddenDigits(new List<int>() { 1, 2, 3 });
var theContext = new FakeHttpContext();
var theKey = "GameState";
theContext.Session.Add(theKey, theGame);
var controller = new Exercise09Controller();
var request = new System.Web.Routing.RequestContext(theContext, new System.Web.Routing.RouteData());
controller.ControllerContext = new System.Web.Mvc.ControllerContext(request, controller);
//Finally, set up the new guess
var theGuess = new List<int>() { 2, 3, 4 };
//Act
controller.GuessTheDigits(theGuess);
var result = controller.ShowPreviousGuesses();
var lastGuess = ((List<Guess>)result.Model).LastOrDefault();
//Assert
/* NOTE : This line forces another implementation decision: to use a
* C# property for Guess.Digits to represent the player's guess.
* */
CollectionAssert.AreEqual(theGuess, lastGuess.Digits);
}
My Unit test breaks on the lastGuess.Digits as this is null. Does this mean I require a constructor initially to create a new list so that isn't null and will not throw the error?
I seem to be going round in circles and don't quite understand what is causing this to not be set. Would it be possible for someone to explain to me why my method isn't adding to my List<Guess> and the best approach for adding my submitted guess to List<Guess>?
Object reference not set to an instance of an object
means that you're using a variable which equals to null, I guess that following lines are problematic:
GuessingGame theGame = this.Session["GameState"] as GuessingGame;
theGame.GuessTheHiddenDigits(guesses);
So in this case theGame is probably not set, because you haven't saved it in Session["GameState"], thus it throws an error because you're trying to call a method on nulled variable.
UPDATE
Since you already know where this error occurs, then you need to know that using a variable which has a null value will result in this kind of error, to prevent it you need to initialize your variables.
First off, use the debugger and when you get that error inspect your objects/properties to see which one is null.
I seem to be going round in circles and don't quite understand what is
causing this to not be set. Would it be possible for someone to
explain to me why my method isn't adding to my List and the
best approach for adding my submitted guess to List?
In GuessingGame.GuessTheHiddenDigits method you are creating a local scope object of type Guess, and adding the passed in List<int> to that ... nowhere are you actually adding anything to your GuessingGame.Guesses list. That 'm' will be removed as soon as that method has finished executing.
Are you then intending to add 'm' to your List?
Like:
Guess m = new Guess();
m.Digits.AddRange(this.guess);
this.guess.Add(m);
Oh, and this.guess doesn't match naming rules for public properties ... call it this.Guess instead.
Disclaimer: I'm very new to Ninject and DI in general. Also, I'm not married to Ninject. If anyone wants to explain how this would work in Windsor, Unity, SourceMap, or something else, I'm all ears.
I've got the following class that handles storing objects of type TArchived:
public class Archiver<TArchived> where TArchived : class
{
public Archiver(Func<string> getName, IStore<TArchived> storage, Func<TArchived> getInitialState);
}
When an instance of Archiver is created, it attempts to look up in storage an instance with the name returned from getName(). If there is no instance, it creates one with the default returned from getInitialState().
The next class uses Archiver to store a list of items. However, while that list of items will never change in size, that list is not known at compile-time.
public class MyClass
{
public class Item
{
public string Value { get; set; }
}
public MyClass(Archiver<Item[]> archiver)
{
Archiver = archiver;
}
public static Item[] GetInitialState(IEnumerable<string> values)
{
return values.Select(value => new Item { Value = value }).ToArray();
}
public Archiver<Item[]> Archiver { get; private set; }
}
I've set up Ninject like so:
public class Tests
{
private IKernel Ninject { get; set; }
public Tests()
{
Ninject = new StandardKernel();
Ninject.Bind<IStore<MyClass.Item[]>>().To<MemoryStore<MyClass.Item[]>>();
Ninject.Bind<Archiver<MyClass.Item[]>>().To<Archiver<MyClass.Item[]>>()
.WithConstructorArgument("getName", new Func<string>(() => "TEST"))
.WithConstructorArgument("getInitialState", new Func<MyClass.Item[]>(MyClass.GetInitialState(/* what here? */)));
}
[Fact]
public void Test()
{
// testing options
var tests = new[] { "A", "B" };
var myClass = Ninject.Get<MyClass>();
}
[Fact]
public void Test_2()
{
// different testing options
var tests = new[] { "A", "B", "C" };
var myClass = Ninject.Get<MyClass>();
}
}
But I'm confused as to what to put for the getInitialState parameter. If I want different lists of items stored by MyClass, I need to pass different items in to the GetInitialState function.
After some more experimentation, these are the best solutions I have come up with. I would love to see a better way.
[Fact]
public void Test()
{
Ninject.Bind<Func<MyClass.Item[]>>().ToProvider<Func<MyClass.Item[]>>(new CallbackProvider<Func<MyClass.Item[]>>((ctx) => () => MyClass.GetInitialState(new[] { "A", "B" })));
var myClass = Ninject.Get<MyClass>();
}
[Fact]
public void Test2()
{
Ninject.Bind<Func<MyClass.Item[]>>().ToConstant<Func<MyClass.Item[]>>(() => MyClass.GetInitialState(new[] { "A", "B", "C" }));
var myClass = Ninject.Get<MyClass>();
}
You can pull a constructor argument out of the binding, and add it at the point of resolution. So use this binding:
Ninject.Bind<Archiver<MyClass.Item[]>>().To<Archiver<MyClass.Item[]>>()
.WithConstructorArgument("getName", new Func<string>(() => "TEST"));
And then use this in each unit test, changing the value of getInitialState as needed:
var myClass = Ninject.Get<MyClass>()
.WithConstructorArgument("getInitialState",
new Func<MyClass.Item[]>(MyClass.GetInitialState(new string[] { "1", "2", "3" }))
);
I havent delved into the depths of your question, but it sounds to me like you're looking for Named Scopes or something very close to that as a way of managing things like this at a higher level. I recommend following the links from there to #Remo Gloor's blog posts on the topics (and adding any missing ones into the NamedScope extension wiki :D).
I created a class that's called UserSessionModel; in it I'm storing some data about the user and in particular I'm storing several json strings that are the results of queries and serializations.
I have several methods and properties in UserSessionModel that overall look like this:
public string SomeUserDataInJson1 { get; set; }
public string SomeUserDataInJson2 { get; set; }
.... 3 more properties like this
public int UserID { get; set; }
private void GetSomeUserDataInJson1
{
ObjectData1 TheObjectData1 = new ObjectData1();
UserQueries TheUserQueries = new UserQueries();
JavascriptSerializer TheSerializer = new JavascriptSerializer();
TheObjectData1 = TheUserQueries.GetData1(TheUserID);
this.SomeUserData1InJson = TheSerializer.Serialize(TheObjectData1);
}
This code is repeated 5 times, with the only change being the ObjectData, the name of the query and the property SomeUserData that's getting set.
Is there a way to make this "better" with an interface or some other c# tools?
Thanks.
Ok, lets assume the following regarding to your example: You're having data for processing with queries defined differently per user (userId).
Our data container class... very simple here, contains only a string.
public class Data
{
public string Content { get; set; }
}
Next step, lets have a look at the query... could be using that interface (could use events, for the response but lets keep it simple here).
public interface IQuery
{
Data Process(Data data);
}
You could have a relation to the user by adding the userId to the IQuery interface but I would prefer to have another interface to solve that:
public interface IUserQueryProvider
{
IEnumerable<IQuery> GetQuerysForUser(uint id);
}
This way you can alter your user to query resolving in a seperate place.
You'll have a serializer/converter, too. Ok, lets make an Interface here for serialization of (processed) data.
public interface ISerializer
{
string Serialize(Data data);
}
Now, lets have a look at implementations, first of all the serializer... doesn't do anything magical here and you should fill in the things you need for serialization of objects (JSON, ...)
public class JavascriptSerializer : ISerializer
{
public string Serialize(Data data)
{
return data.Content; //whatever you want do instead for serialization
}
}
Now let us go to our Queries. I assume you're not very familiar with design patterns and you're meaning something like a Command Pattern instead (for processing jobs, see my link in the comments for more info about design pattern). 3 implementations follows as samples:
public class ReplaceQuery : IQuery
{
private readonly string match;
private readonly string text;
public ReplaceQuery(string match, string text)
{
this.match = match;
this.text = text;
}
public Data Process(Data data)
{
return data.Content.Contains(match) ? new Data {Content = data.Content.Replace(match, text)} : null;
}
}
public class GreetingToQuery : IQuery
{
private readonly string greeting;
private readonly string place;
public GreetingToQuery(string greeting, string place)
{
this.greeting = greeting;
this.place = place;
}
public Data Process(Data data)
{
return data.Content.Contains(greeting) ? new Data {Content = data.Content + place + "."} : null;
}
}
public class LineEndingQuery : IQuery
{
public Data Process(Data data)
{
return data.Content.LastIndexOf(".", StringComparison.Ordinal) == data.Content.Length - 1 &&
data.Content.Length > 0
? new Data {Content = "\n"}
: null;
}
}
If we want to resolve which querys belongs to a user we need our IUserQueryProvider implementation. It is nothing more than a dictionary in this case (but could be easyly switched to other implementations).
public class SampleQueryProvider : Dictionary<uint, IEnumerable<IQuery>>, IUserQueryProvider
{
public IEnumerable<IQuery> GetQuerysForUser(uint id)
{
IEnumerable<IQuery> queries;
TryGetValue(id, out queries);
return queries;
}
}
Last but not least... the glue for everything. I added another Interface here for our "generator engine".
public interface IScriptGenerator
{
event Action<string> Script;
void Generate(Data data, IEnumerable<IQuery> queries);
}
To make it more flexible I made the interface/implementation following a design principle introduced by Ralf Westphal called Event Based Components (EBC). Google is your friend if you are interested in this topic.
public class SampleScriptGenerator : IScriptGenerator
{
private readonly ISerializer serializer;
public event Action<string> Script;
public SampleScriptGenerator(ISerializer serializer)
{
this.serializer = serializer;
}
public void Generate(Data data, IEnumerable<IQuery> queries)
{
foreach (string serialized in from query in queries select query.Process(data) into result where result != null select serializer.Serialize(result))
{
OnSerialize(serialized);
}
}
private void OnSerialize(string serialized)
{
var handler = Script;
if (handler != null) handler(serialized);
}
}
And now lets put it all together and let us fly:
static void Main()
{
var generator = new SampleScriptGenerator(new JavascriptSerializer());
generator.Script += Console.Write; // bind to console output here
var queryProvider = new SampleQueryProvider
{
{
1, // user with id 1
new List<IQuery>
{
new ReplaceQuery("<name>", "frenchie"),
new GreetingToQuery("bonjour", "the universe"),
new LineEndingQuery()
}
},
{
2, // user with id 2
new List<IQuery>
{
new ReplaceQuery("<name>", "stegi"),
new GreetingToQuery("hello", "the world"),
new LineEndingQuery()
}
}
};
var data1 = new Data {Content = "My name is <name>."};
var data2 = new Data {Content = "I say hello to "};
var data3 = new Data {Content = "I say bonjour to "};
var data4 = new Data {Content = "."};
// you cold combine data and user query execution into lists and loops, too
generator.Generate(data1, queryProvider.GetQuerysForUser(1));
generator.Generate(data2, queryProvider.GetQuerysForUser(1));
generator.Generate(data3, queryProvider.GetQuerysForUser(1));
generator.Generate(data4, queryProvider.GetQuerysForUser(1));
generator.Generate(data1, queryProvider.GetQuerysForUser(2));
generator.Generate(data2, queryProvider.GetQuerysForUser(2));
generator.Generate(data3, queryProvider.GetQuerysForUser(2));
generator.Generate(data4, queryProvider.GetQuerysForUser(2));
Console.ReadKey();
}
}
You should see something like:
My name is frenchie.
I say bonjour to the universe.
My name is stegi.
I say hello to the world.
As your homework... try to add your own query implementation and data to process. How would you add recursion here? ;-)
Firstly you should definitely use a List<string> or string[]. Then you can increase code space, and extensibility. You can loop through and load data into the list like your doing there. Another thing, did you mean TheQueries by TheUserQueries, as I can't see the latter declared or the former used.
If you ever find yourself creating more than two similar property like you have done, you should probably use a List.
Secondly, the point of an interface is to force an object to implement certain methods etc. that can then be called and accessed in other classes. If that will help you, then you can put your method in an interface. Otherwise there's really no point.