Skip to content

Instantly share code, notes, and snippets.

@dtchepak
Last active January 4, 2016 04:19
Show Gist options
  • Save dtchepak/8567647 to your computer and use it in GitHub Desktop.
Save dtchepak/8567647 to your computer and use it in GitHub Desktop.
Example of using a queue to run multiple actions with NSubstitute `When..Do`. [Disclaimer: for illustrative purposes only. Use at your own risk!]
using System;
using System.Collections.Generic;
using System.Linq;
using NSubstitute;
using NSubstitute.Core;
using NUnit.Framework;
using Shouldly;
//Disclaimer: for illustrative purposes only. Use at your own risk! :)
namespace Sample
{
public static class DoExtensions
{
public static DoQueue FirstDo<T>(this WhenCalled<T> a, Action<CallInfo> action)
{
var queue = DoQueue.First(action);
a.Do(queue.Next);
return queue;
}
}
public class DoQueue
{
public static DoQueue FirstRepeat(Action<CallInfo> value, int times) { return new DoQueue().ThenRepeat(value, times); }
public static DoQueue First(Action<CallInfo> value) { return new DoQueue().Then(value); }
private readonly Queue<Action<CallInfo>> _queue = new Queue<Action<CallInfo>>();
private Action<CallInfo> _infiniteRepeat = x => { };
private DoQueue() { }
public DoQueue Then(Action<CallInfo> value) { _queue.Enqueue(value); return this; }
public DoQueue ThenRepeat(Action<CallInfo> value, int times)
{
foreach (var v in Enumerable.Repeat(value, times)) { Then(v); }
return this;
}
public void ThenAlways(Action<CallInfo> value) { _infiniteRepeat = value; }
public void Next(CallInfo info)
{
if (_queue.Count > 0) _queue.Dequeue().Invoke(info);
else _infiniteRepeat(info);
}
}
public class WhenMultipleDo
{
public interface IFoo
{
void Bar();
}
[Test]
public void CheckMultiples()
{
var sub = Substitute.For<IFoo>();
int counter = 0;
string msg = "";
sub.When(x => x.Bar())
.FirstDo(x => { throw new Exception(); })
.Then(x => msg = "setting msg")
.ThenAlways(x => counter++);
Should.Throw<Exception>(() => sub.Bar());
sub.Bar();
msg.ShouldBe("setting msg");
sub.Bar();
counter.ShouldBe(1);
sub.Bar();
counter.ShouldBe(2);
sub.Bar();
counter.ShouldBe(3);
}
[Test]
public void StopDoing()
{
var sub = Substitute.For<IFoo>();
int counter = 0;
sub.When(x => x.Bar())
.FirstDo(x => counter++);
sub.Bar();
sub.Bar();
sub.Bar();
sub.Bar();
counter.ShouldBe(1);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment