How do I run code before every test run in MSpec? - c#

I'm trying to run some initialization code before a test. I've tried the suggestions in other questions, but it doesn't seem to work. My domain model raises events via the following class:
public static class DomainEvents
{
private static readonly object #lock = new object();
private static Action<IDomainEvent> raiseEvent;
public static void Raise<TEvent>(TEvent #event) where TEvent : class, IDomainEvent
{
// omitted for brevity
}
public static void RegisterEventPublisher(Action<IDomainEvent> eventPublisher)
{
lock (#lock)
{
raiseEvent = eventPublisher;
}
}
}
For testing purposes I would like to capture these events in a static list. What is the best way of doing this?
Update
The problem was caused by the order in which the tests are run (which as Alexander points out below, is not guaranteed). In one of my specs I had registered a mock event publisher. The fact that the spec would often run in different orders meant that a) to begin with I didn't know I had the issue (the "problem" spec always ran last) and b) Once I started having the issue, the number of failing tests would often vary between runs (making it even more confusing).
The lesson learned - clean up any static resources after each context has run. You can do this by implementing ICleanupAfterEveryContextInAssembly.

Maybe I'm misunderstanding the issue, but the basic pattern is:
public class WhenSomeDomainEventIsRaised
{
private IList<IDomainEvent> EventsRaised = new List<IDomainEvent>();
Establish context = () =>
{
// subscribe to events; when raised, add to EventsRaised list
}
}
If you want to do this for all tests or a subset of tests:
public abstract class DomainSpecification
{
protected IList<IDomainEvent> EventsRaised = new List<IDomainEvent>();
Establish context = () =>
{
// subscribe to events; when raised, add to EventsRaised list
}
}
You can have all specs that need this behaviour inherit from this class, and MSpec will take care of running all Establish blocks along the inheritance hierarchy.

This works for me:
using System;
using System.Collections.Generic;
using Machine.Specifications;
namespace AssemblyContextSpecs
{
public static class DomainEvents
{
static readonly object #lock = new object();
static Action<IDomainEvent> raiseEvent;
public static void Raise<TEvent>(TEvent #event) where TEvent : class, IDomainEvent
{
raiseEvent(#event);
}
public static void RegisterEventPublisher(Action<IDomainEvent> eventPublisher)
{
lock (#lock)
{
raiseEvent = eventPublisher;
}
}
}
public interface IDomainEvent
{
}
class FooEvent : IDomainEvent
{
}
public class DomainEventsContext : IAssemblyContext
{
internal static IList<IDomainEvent> Events = new List<IDomainEvent>();
public void OnAssemblyStart()
{
DomainEvents.RegisterEventPublisher(x => Events.Add(x));
}
public void OnAssemblyComplete()
{
}
}
public class When_a_domain_event_is_raised
{
Because of = () => DomainEvents.Raise(new FooEvent());
It should_capture_the_event =
() => DomainEventsContext.Events.ShouldContain(x => x.GetType() == typeof(FooEvent));
}
}
Shouldn't RegisterEventPublisher rather be RegisterEventSubscriber?

Related

Reflection only successful on first call in Blazor-State-Management

I discovered a weird behavior where I absolutely don't know where it comes from or how to fix it.
The issue arises with the blazor-state management (which is based on the mediator pattern) - library can be found here: https://timewarpengineering.github.io/blazor-state/.
Lets assume we have the following base class for an enumeration:
public abstract class Simple<TSimple> where TSimple: Simple<TSimple>
{
private readonly string _key;
protected Simple(string key)
{
_key = key;
}
public virtual string Key => _key;
public static TSimple Create(string key)
{
var obj = All.SingleOrDefault(e => e.Key == key);
return obj;
}
public static IReadOnlyCollection<TSimple> All => GetAll();
private static IReadOnlyCollection<TSimple> GetAll()
{
var enumerationType = typeof(TSimple);
return enumerationType.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy)
.Where(info => enumerationType.IsAssignableFrom(info.FieldType))
.Select(info => info.GetValue(null))
.Cast<TSimple>()
.ToArray();
}
}
And the following enumeration implementation:
public class SimpleImpl : Simple<SimpleImpl>
{
public static readonly SimpleImpl One = new SimpleImpl("Important");
public static readonly SimpleImpl Two = new SimpleImpl("Urgent");
public static readonly SimpleImpl Three = new SimpleImpl("ImportantAndUrgent");
public static readonly SimpleImpl Four = new SimpleImpl("None");
private SimpleImpl(string key) : base(key)
{
}
}
So far so good.
I use this enumeration in a blazor app, where the data is retrieved via gRPC-Web from the backend, is transformed and added to the state.
So the code section of the Index.cshtml looks something like this:
#code
{
private AppState AppState => GetState<AppState>();
protected override async Task OnInitializedAsync()
{
foreach (var simple in new[] {"Important", "Urgent", "ImportantAndUrgent", "None"})
{
await Mediator.Send(new AppState.AddAction(simple));
}
}
This gets handled by the Handler:
public partial class AppState
{
public class AppHandler : ActionHandler<AddAction>
{
private AppState AppState => Store.GetState<AppState>();
public AppHandler(IStore store) : base(store)
{
}
public override async Task<Unit> Handle(AddAction aAction, CancellationToken aCancellationToken)
{
var simple = SimpleImpl.Create(aAction.Simple);
Console.WriteLine(simple == null); // First call false, afterwards true
AppState.Simples.Add(simple); // If I don't add the object to the state, Simple.Create always returns an object
return await Unit.Task;
}
}
}
And here is the problem. On the first try everything works, but if the functions gets called a second time (so my gRPC-Client returns multiple items) simple will always be null. If I remove the AppState.Simples.Add(simple) then it works again.
If I add the following code: Console.WriteLine(string.Join(",", SimpleImpl.All.Select(s => s.Key)); on the first run it prints all the possible values:
Important,Urgent,ImportantAndUrgent,None
On the second run, this:
,Urgent,,
Urgent was in the Dto in the first run. So it seems something to do with how the reference in the List is kept alive (which should not interfer with how the reflection part in Simple works).
Furthermore: in the GetAll() function of Simple everything works fine until the Select(info => .GetValue(null)) The FieldInfo-Property itself holds all 4 options. After GetValue and the cast there is only the last choosen one "alive".
The State-Entity looks like the following:
public partial class AppState : State<AppState>
{
public IList<SimpleImpl> Simples { get; private set; }
public override void Initialize()
{
Simples = new List<SimpleImpl>();
}
}
And the Action of this sample:
public partial class AppState
{
public class AddAction : IAction
{
public AddAction(string simple)
{
Simple = simple;
}
public string Simple { get; }
}
}
This code is running under .NET Core 3.1.
If anybody has a tip where the problem lays I would be very thankful.
Thanks to #steven-t-cramer how helped me on finding the issue.
Basically it all boils down to the Mediator.Send and State-Handling.
In the Blazor-State library a clone is created when one dispatches and handles an action (so you as a developer don't have to take care of that). But exactly this cloning messed up big time here because of the static nature of Simple(basically an enumeration class).
To get around that, the state can implement ICloneable and do this stuff on its own.
A very naive way to do would be that:
public partial class AppState : State<AppState>, ICloneable
{
private List<SimpleImpl> _simples = new List<SimpleImpl>();
public IReadOnlyList<SimpleImpl> Simples => _simples.AsReadOnly();
public override void Initialize()
{
_simples = new List<SimpleImpl>();
}
public object Clone()
{
var state = new AppState { _simples = _simples};
return state;
}
}

ReactiveExtension that was working on old computer is now failing

I'm using the code from Weak Events in .Net, the easy way to handle monitoring changes to an observable collection. The code has worked without any problems for months. I recently updated to a new computer. After getting everything setup and pulling down the code from my repository I encountered a strange problem. The code no longer works!
Here's the relevant portion of my code, it all takes place in the constructor:
public class PurchaseOrderReceipt : BaseEntity
{
/// <summary>
/// Initializes a new instance of the <see cref="PurchaseOrderReceipt" /> class.
/// </summary>
public PurchaseOrderReceipt()
{
this.ReceiptItems = new ObservableCollection<PurchaseOrderItemReceipt>();
this.DateReceived = DateTime.Now;
this.ReceiptItems.ObserveCollectionChanged()
.SubscribeWeakly(this, (target, eventArgs) => target.ReceiptItemsChanged());
}
The exception is thrown on the SubscribeWeakly line with the following error message: ArgumentException: onNext must refer to a static method, or else the subscription will still hold a strong reference to target
I can recreate the problem in LinqPad just by creating an instance of the PurchaseOrderReceipt.
Odder still if I write a simple class in LinqPad that mirrors the setup in the PurchaseOrderReceipt class than it works.
LinqPad code:
void Main()
{
var x = new Test();
x.ReceiptItems.Add(new PurchaseOrderItemReceipt());
}
public class Test:BaseEntity
{
public ObservableCollection<PurchaseOrderItemReceipt> ReceiptItems {get; set;}
public Test()
{
this.ReceiptItems = new ObservableCollection<PurchaseOrderItemReceipt>();
this.ReceiptItems.ObserveCollectionChanged().SubscribeWeakly(this,(target, eventargs) => target.TestChanged());
}
private void TestChanged()
{
"Changed!".Dump();
}
}
Changed! is printed out in the results window.
Here's the CustomReactiveExtension class from the link at the top.
public static class CustomReactiveExtension
{
public static IObservable<EventPattern<NotifyCollectionChangedEventArgs>> ObserveCollectionChanged(this INotifyCollectionChanged collection)
{
return Observable.FromEventPattern<NotifyCollectionChangedEventHandler, NotifyCollectionChangedEventArgs>(
handler => (sender, e) => handler(sender, e),
handler => collection.CollectionChanged += handler,
handler => collection.CollectionChanged -= handler);
}
public static IDisposable SubscribeWeakly<T, TTarget>(this IObservable<T> observable, TTarget target, Action<TTarget, T> onNext) where TTarget : class
{
var reference = new WeakReference(target);
if (onNext.Target != null)
{
throw new ArgumentException("onNext must refer to a static method, or else the subscription will still hold a strong reference to target");
}
IDisposable subscription = null;
subscription = observable.Subscribe(item =>
{
var currentTarget = reference.Target as TTarget;
if (currentTarget != null)
{
onNext(currentTarget, item);
}
else
{
subscription.Dispose();
}
});
return subscription;
}
}
Any ideas?
I am not 100% certain but my guess is that either different versions of the compiler or different compilation options are resulting in your lambda being compiled to an instance method rather than a static method.
The easiest solution to this would be to explicitly implement a static method to be used as your onNext callback, i.e:
private static void OnReceiptItemsChanged(PurchaseOrderReceipt target,
EventPattern<NotifyCollectionChangedEventArgs> eventPattern)
{
// TODO Do something here
}
And then use SubscribeWeakly like so:
this.ReceiptItems.ObserveCollectionChanged().SubscribeWeakly(this, OnReceiptItemsChanged);
Now regardless of which compiler you use or which compilation options the callback is always a static method.

Automatically calling an init function whenever an object is used for the 1st time

I have an object that only initializes itself with barebones data when constructed (fast), and loads itself for real (slow) when first accessed. The idea is that I'm creating a lot of these barebones objects at startup and hash them into a map, then fully load each object whenever it is individually accessed for the first time. The problem is that I cannot guarantee how clients will interact with this object, there are multiple public methods that might be invoked.
Is there a good pattern to support this kind of situation? The obvious (and my current) solution is to track state with an internal bool, check against that bool in every function that might be invoked, and load that way. But that requires code duplication of that behavior across all public functions, and is vulnerable to errors.
I can imagine a single point-of-entry method that then dishes out behaviors based on a client request type etc., but before I go consider going down that road I want to see if there's a commonly accepted approach/pattern that I might not be aware of. I'm doing this in C#, but any insight is appreciated.
If I understood what you want to achieve, you are looking for the Proxy Design Pattern, more specifically, a virtual Proxy.
Refer to http://www.dofactory.com/net/proxy-design-pattern
A small example would be something like:
public abstract class IObjectProvider
{
public abstract IObjectProvider Object{get;}
public abstract void doStuff();
}
public class RealObject : IObjectProvider
{
public RealObject()
{
//Do very complicated and time taking stuff;
}
public override IObjectProvider Object
{
get { return this; }
}
public override void doStuff()
{
//do this stuff that these objects normally do
}
}
public class ObjectProxy : IObjectProvider
{
private IObjectProvider objectInstance = null;
public override IObjectProvider Object
{
get
{
if (objectInstance == null)
objectInstance = new RealObject();
return objectInstance;
}
}
public override void doStuff()
{
if(objectInstance!=null)
objectInstance.doStuff();
}
}
public class SkeletonClass
{
public IObjectProvider Proxy1 = new ObjectProxy();
public IObjectProvider Proxy2 = new ObjectProxy();
}
static void Main(String[] args)
{
//Objects Not Loaded
SkeletonClass skeleton = new SkeletonClass();
//Proxy1 loads object1 on demand
skeleton.Proxy1.Object.doStuff();
//Proxy2 not loaded object2 until someone needs it
}
Here's an example of dynamic proxy approach.
using System;
using System.Diagnostics;
using Castle.DynamicProxy; //Remember to include a reference, too. It's nugettable package is Castle.Core
namespace ConsoleApp
{
public class ActualClass
{
//Have static instances of two below for performance
private static ProxyGenerator pg = new ProxyGenerator();
private static ActualClassInterceptor interceptor = new ActualClassInterceptor();
//This is how we get ActualClass items that are wrapped in the Dynamic Proxy
public static ActualClass getActualClassInstance()
{
ActualClass instance = new ActualClass();
return pg.CreateClassProxyWithTarget<ActualClass>(instance, interceptor);
}
//Tracking whether init has been called
private bool initialized = false;
//Will be used as evidence of true initialization, i.e. no longer null
private int? someValue = null;
public void Initialize()
{
if (!initialized)
{
//do some initialization here.
someValue = -1; //Will only get set to non-null if we've run this line.
initialized = true;
}
}
//Any methods you want to intercept need to be virtual!
public virtual int replaceValue(int value)
{
//below will blow up, if someValue has not been set to -1 via Initialize();
int oldValue = someValue.Value;
someValue = value;
return oldValue;
}
//block off constructor from public to enforce use of getActualClassInstance
protected ActualClass() { }
}
public class ActualClassInterceptor : ActualClass, IInterceptor
{
public void Intercept(IInvocation invocation)
{
//Call initialize before proceeding to call the intercepted method
//Worth noting that this is the only place we actually call Initialize()
((ActualClass)invocation.InvocationTarget).Initialize();
invocation.Proceed();
}
}
class Program
{
static void Main(string[] args)
{
ActualClass instance1 = ActualClass.getActualClassInstance();
ActualClass instance2 = ActualClass.getActualClassInstance();
int x1 = instance1.replaceValue(41);
int x2 = instance2.replaceValue(42);
int y1 = instance1.replaceValue(82);
Debug.Assert(y1 == 41);
int y2 = instance2.replaceValue(84);
Debug.Assert(y2 == 42);
var read = Console.ReadKey();
}
}
}

Getting resolved types inside a Ninject module

Problem:
in my domain layer assembly I store two interfaces:
public interface IDomainEvent { }
and
public interface IHandle<T> where T: IDomainEvent, new()
EventDispatcher class is defined there also:
public static class EventDispatcher {
[ThreadStatic]
private static List<Delegate> actions;
[ThreadStatic]
private static List<Object> handlers;
public static List<Object> Handlers {
get { return handlers; }
set { handlers = value; }
}
public static void Register<T>(Action<T> callback) where T : IDomainEvent, new() {
if(null == actions) {
actions = new List<Delegate>();
actions.Add(callback);
}
}
public static void ClearCallbacks() {
actions = null;
}
public static void Raise<T>(T #event) where T : IDomainEvent, new() {
if(null != Handlers) {
foreach(var handler in Handlers.Where(h => h is IHandle<T>)) {
((IHandle<T>)handler).Handle(#event);
}
}
if(null != actions) {
foreach(var action in actions) {
if(action is Action<T>) {
((Action<T>)action)(#event);
}
}
} // if(null != actions) {
}
}
There's a module in presentation layer assembly:
public class EventDispatchingModule : NinjectModule {
public override void Load() {
// EventDispatcher.Handlers = this.Kernel.GetAll(IHandle<T>); Can't do that!
// Bind<IHandle<CarHasBeenRegisteredEvent>>().To<CarHasBeenRegisteredHandler();
}
}
So I can't call Kernel.GetAll(IHandle<T>) there because it can't resolve T parameter.
Howcome I resolve this?
Thanks!
No need to use a module (I've not used ninject, but something similar):
// Put these in the domain project
public class EventDispatcher
{
private static IEventDispatcher _dispatcher;
public static void Setup(IEventDispatcher dispatcher)
{
_dispatcher = dispatcher;
}
public static void Dispatch<T>(T domainEvent) where T : IDomainEvent
{
_dispatcher.Dispatch<T>(domainEvent);
}
}
public interface IEventDispatcher
{
public void Dispatch<T>(T domainEvent) where T : IDomainEvent;
}
// and this one in the project which has Ninject
public class NinjectEventDispatcher : IEventDispatcher
{
private static IKernel _container;
public NinjectEventDispatcher(IKernel container)
{
_container = container;
}
public void Dispatch<T>(T domainEvent) where T : IDomainEvent
{
foreach (var listener in _container.GetAll<IHandle<T>>())
{
listener.Handle(domainEvent);
}
}
}
// And after the container have been configured:
EventDispatcher.Setup(new NinjectEventDispatcher(_container));
But I don't know how ninject handles scoped objects (which may also want to receive the events).
My container has domain events built in, read more in this article: http://www.codeproject.com/Articles/440665/Having-fun-with-Griffin-Container
Update:
I've updated the code sample to make the domain project unaware of Ninject.
You are not using Service Location with this code. The internals of the event dispatcher is. i.e. none of your code is affected by it.
You can get all Handlers with following code
Kernel.GetAll(typeof (IHandle<>));
But anyway it's not good idea to load all IHanders in NInjectModule because you don't know if another modules are already loaded or not (and another modules can register Handlers too).
I suggest make EventDispatcher class not static and register it in scope that you need (If you need new handlers for each request - in request scope, otherwise - in singleton scope . Handlers you can inject with constructor like :
Kerner.Bind<EventDispatcher>().ToSelf()
.InRequestScope()
.WithConstructorArgument("handlers", c => c.Kernel.GetAll(typeof(IHandler<>)))
Hope this helps

Using structuremap to Register Generic Types

I am new to structuremap. I am trying to get Structuremap to auto-register
public void RegisterAllEventHandlers()
{
Scan(cfg =>
{
cfg.TheCallingAssembly();
//cfg.IncludeNamespaceContainingType<NewCustomerCreated>();
cfg.IncludeNamespace("ParentNameSpace");
cfg.AddAllTypesOf(typeof (IHandle<NewCustomerCreated>));
});
//For(typeof (IHandle<>)).Use(typeof (NewCustomerCreated));
}
NewCustomerCreated is the event and I want to register all Handlers for this event ie ones using IHandle<NewCustomerCreated>
The following code is working but I am sure there it can be done by scanning :-
ObjectFactory.Initialize(x =>
{
x.For(typeof(IHandle<NewCustomerCreated>))
.Add(new NewCustomerCreatedHandler());
x.For(typeof(IHandle<NewCustomerCreated>))
.Add(new SendWelcomeEmailToNewCustomer());
});
I am trying to use DomainEvent raiser from
http://blog.robustsoftware.co.uk/2009/08/better-domain-event-raiser.html
** I would appreciate if someone can edit the question to reflect what I am asking in a better way **
Thank you,
Mar
Edit 1: Adding Code from blog
public interface IEventDispatcher
{
void Dispatch<TEvent>(TEvent eventToDispatch) where TEvent : IDomainEvent;
}
public static class DomainEventDispatcher
{
public static IEventDispatcher Dispatcher { get; set; }
public static void Raise<TEvent>(TEvent eventToRaise) where TEvent : IDomainEvent
{
Dispatcher.Dispatch(eventToRaise);
}
}
public class StructureMapEventDispatcher : IEventDispatcher
{
public void Dispatch<TEvent>(TEvent eventToDispatch) where TEvent : IDomainEvent
{
foreach (var handler in ObjectFactory.GetAllInstances<IHandle<TEvent>>())
{
handler.Handle(eventToDispatch);
}
}
From my test project I am calling registry class which will scan the assembly
public void RegisterAllEventHandlers()
{
Scan(cfg =>
{
cfg.TheCallingAssembly();
cfg.IncludeNamespace("Project1");
//cfg.AddAllTypesOf(typeof(IHandle<NewCustomerCreated>));
cfg.ConnectImplementationsToTypesClosing(typeof(IHandle<>));
});
// This initializes correctly
//ObjectFactory.Initialize(x =>
//{
// x.For(typeof(IHandle<NewCustomerCreated>)).Add(new NewCustomerCreatedHandler());
//});
// Handler returns 0 count
var handler =ObjectFactory.GetAllInstances<IHandle<NewCustomerCreated>>();
}
and then
var eventDispatcher = new StructureMapEventDispatcher();
DomainEventDispatcher.Dispatcher = eventDispatcher;
Try this:
cfg.AddAllTypesOf(typeof (IHandle<>));
Then your container will do the rest:
var handler = container.GetInstance<IHandler<NewCustomerCreated>>();
If you need more control take a look at this:
https://stackoverflow.com/questions/516892/structuremap-auto-registration-for-generic-types-using-scan

Categories