Is there a way to mock system events in C# such as SystemEvents.PowerModeChanged and artificially raise them in a MOQ setup?
A litte bit late, but here is an example for the implementation with an interface in front of SystemEvent Matt mentioned:
Interface:
public interface ISystemEvents
{
event PowerModeChangedEventHandler PowerModeChanged;
}
Adapter class:
public class SystemEventsAdapter : ISystemEvents
{
public event PowerModeChangedEventHandler PowerModeChanged;
}
Your registration on the event:
public class TestClass {
private readonly ITestService _testService;
public TestClass(ISystemEvents systemEvents, ITestService testService) {
_testService = testService;
systemEvents.PowerModeChanged += OnPowerModeChanged;
}
private void OnPowerModeChanged(object sender, PowerModeChangedEventArgs e)
{
if (e.Mode == PowerModes.Resume)
{
_testService.DoStuff();
}
}
}
Test:
[TestFixture]
public class TestClassTests
{
private TestClass _cut;
private Mock<ISystemEvents> _systemEventsMock;
private Mock<ITestService> _testServiceMock;
[SetUp]
public void SetUp()
{
_systemEventsMock = new Mock<ISystemEvents>();
_testServiceMock = new Mock<ITestService>();
_cut = new TestClass(
_systemEventsMock.Object,
_testServiceMock.Object
);
}
[TestFixture]
public class OnPowerModeChanged : TestClassTests
{
[Test]
public void When_PowerMode_Resume_Should_Call_TestService_DoStuff()
{
_systemEventsMock.Raise(m => m.PowerModeChanged += null, new PowerModeChangedEventArgs(PowerModes.Resume));
_testServiceMock.Verify(m => m.DoStuff(), Times.Once);
}
}
}
No, not directly.
I see two ways to achieve this :
By Implementing an interface in front of the systemEvent
By using a detouring framework such as Moles Framework or the Microsoft Fakes
Related
I am working on a workflow project that has 19 scenarios for testing the whole system and 34 steps.
So, my question is, how can I create an automation test for it?
My current approach is:
Create an integrated test per each scenario, and then create the main system test to run all integrated tests.
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
namespace Project1
{
// Unit tests
public class UnitTest_step1
{
public void RunTest() { }
}
public class UnitTest_step2
{
public void RunTest() { }
}
public class UnitTest_step3
{
public void RunTest() { }
}
public class UnitTest_step4
{
public void RunTest() { }
}
// End of unit tests
public class IntegrationTests
{
public void IntegrationTest1()
{
UnitTest_step1.RunTest();
UnitTest_step2.RunTest();
UnitTest_step4.RunTest();
}
public void IntegrationTest2()
{
UnitTest_step1.RunTest();
UnitTest_step2.RunTest();
UnitTest_step3.RunTest();
UnitTest_step4.RunTest();
}
public void IntegrationTest3()
{
UnitTest_step1.RunTest();
UnitTest_step4.RunTest();
}
}
[TestClass]
public class SystemTests
{
[TestMethod]
public void Scenario1()
{
IntegrationTests.IntegrationTest1()
}
[TestMethod]
public void Scenario2()
{
IntegrationTests.IntegrationTest2();
}
[TestMethod]
public void Scenario3()
{
IntegrationTests.IntegrationTest3();
}
[TestMethod]
public void ScenarioN()
{
IntegrationTests.IntegrationTestN();
}
}
}
Best Regards.
Well, in my opinion, the information provided in your question is very abstract and the question is a bit too broad.
The answer depends on how your workflow engine is implemented and what are your system requirements.
Requirements and implementation details are what defines your approach to testing.
I would start with clarifying what kind of steps you have, is there any data context is passed,
what side effects these steps produce (writes data to database, sends events, call other system APIs, etc.),
do steps depend on each other and so on.
Another question is how do you need to assert the results, after each step or after scenario?
The system should be testable and normally, each step should be covered with unit tests.
So, suggested hypothetical approach is to cover each step with isolated unit tests
and scenarios with integration tests.
I came up with a simple example just to illustrate one of the general approaches.
For simplicity, I assume that steps have little or no data context and can be reordered.
namespace Workflow.Test
{
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
[TestClass]
public class SystemTests
{
[TestMethod]
public void Scenario1()
{
new Workflow().Run(new Scenario1());
}
[TestMethod]
public void Scenario2()
{
new Workflow().Run(new Scenario2());
}
// The advantage of explicit steps declaration is test readability.
// Declarative approach also enables the further possibility of test generation!
[TestMethod]
public void MoreExplicitAndDeclarative()
{
new Workflow().Run(new List<Type>
{
typeof(Step1),
typeof(Step2),
typeof(Step3),
});
}
// Step instantiation may be needed if you want to parameterize some steps.
[TestMethod]
[DataRow("Custom step")]
[DataRow("Another step")]
public void MoreExplicitParameterizedScenario(string customName)
{
new Workflow().Run(new List<IRunnable>{
new Step1(),
new Step3(customName)
});
}
}
[TestClass]
public class StepsUnitTests
{
[TestMethod]
public void Step1DoesWhatWeWant()
{
// Mock dependencies
new Step1().Run();
// Assert results
}
}
#region Workflow Engine Example
public interface IRunnable
{
void Run();
}
public class Workflow
{
public void Run(Scenario scenario)
{
Run(CreateSteps(scenario.GetStepTypes()));
}
public void Run(IEnumerable<Type> stepTypes)
{
Run(CreateSteps(stepTypes));
}
public void Run(List<IRunnable> steps)
{
steps.ForEach(step => step.Run());
}
private List<IRunnable> CreateSteps(IEnumerable<Type> stepTypes)
{
var steps = new List<IRunnable>();
foreach (var stepType in stepTypes)
{
steps.Add(CreateStep(stepType));
}
return steps;
}
private IRunnable CreateStep(Type stepType)
=> (IRunnable) Activator.CreateInstance(stepType);
}
#endregion
// Step structure can differ according to system requirements.
// We may add data context and link steps into pipeline if needed.
#region Steps
public abstract class Step : IRunnable
{
private readonly string _stepName;
protected Step(string name)
{
_stepName = name;
}
public void Run()
{
Console.WriteLine($"{_stepName} in action.");
Invoke();
}
public abstract void Invoke();
}
public class Step1 : Step
{
public Step1() : base(nameof(Step1))
{
}
public override void Invoke()
{
// do work
Console.WriteLine($"Step1 invoked.");
}
}
public class Step2 : Step
{
public Step2() : base(nameof(Step2))
{
}
public override void Invoke()
{
// do work
Console.WriteLine($"Step2 invoked.");
}
}
public class Step3 : Step
{
public Step3(string customName) : base(customName)
{
}
public Step3() : this(nameof(Step3))
{
}
public override void Invoke()
{
// do work
Console.WriteLine($"Step3 invoked.");
}
}
public class Step4 : Step
{
public Step4() : base(nameof(Step4))
{
}
public override void Invoke()
{
// do work
Console.WriteLine($"Step4 invoked.");
}
}
#endregion
// Scenarios should be as declarative as possible.
// Let's say the scenario is just specification of what steps (step Type)
// and in what order should be executed (List as a non-unique ordered collection).
#region Scenarios
public abstract class Scenario
{
public abstract List<Type> GetStepTypes();
}
public class Scenario1 : Scenario
{
public override List<Type> GetStepTypes()
=> new List<Type>
{
typeof(Step1),
typeof(Step2),
typeof(Step3)
};
}
public class Scenario2 : Scenario
{
public override List<Type> GetStepTypes()
=> new List<Type>
{
typeof(Step1),
typeof(Step2),
typeof(Step4)
};
}
#endregion
}
I am doing some unit tests with NUnit and NSubstiture.
I have this class:
public class Presenter
{
public Presenter()
{
}
private readonly IView _view;
public Presenter(IView view)
{
_view = view;
this._view.Loaded += OnLoaded;
}
private void OnLoaded()
{
_view.Render("Hello Word");
}
}
And I have this Interface:
public interface IView
{
event Action Loaded;
void Render(string text);
}
And I have already a unit test with the NSubstiture framework, like this:
[Test]
public void ctor_WhenViewIsLoaded_CallsViewRender_WithMockingFramework()
{
var mockView = Substitute.For<IView>();
Presenter p = new Presenter(mockView);
mockView.Loaded += Raise.Event<Action>();
mockView.Received().Render(Arg.Is<string>(s => s.Contains("Hello World")));
}
But now I want for just testing purpose, write the same unit test , but then without the NSubstiture framework:
[Test]
public void ctor_WhenViewIsLoaded_CallsViewRender_WithoutMockingFramework()
{
IView view;
Presenter MockingVIew = new Presenter(view);
}
But how to do this?
Thank you
I try it like this:
public class FakePresenter : IView
{
public event Action Loaded;
public void Render(string text)
{
}
}
[Test]
public void ctor_WhenViewIsLoaded_CallsViewRender_WithoutMockingFramework()
{
//FakeMockingVIew = new Presenter(view);
FakePresenter fPresenter = new FakePresenter();
Presenter p = new Presenter(fPresenter);
fPresenter.Loaded += Raise.Event<Action>();
fPresenter.Received();
Assert.That(fPresenter, Is.EqualTo());
}
If you no longer want to use the mocking framework, nothing is stopping you from creating a class derived from IView yourself and using that as the dependency in the test
public class MyTestClass {
public class FakePresenter : IView {
public event Action Loaded = delegate { };
public void Render(string text) {
RenderedText = text;
}
public string RenderedText { get; private set; }
public void Load() {
Loaded();
}
}
[Test]
public void ctor_WhenViewIsLoaded_CallsViewRender_WithoutMockingFramework() {
//Arrange
var fake = new FakePresenter();
var subject = new Presenter(fake);
var expected = "Hello Word";
//Act
fake.Load();
var actual = fake.RenderedText;
//Assert
Assert.AreEqual(expected, actual);
}
}
The above implementation of the dependency exposes a Load() method to raise the event for all subscribers and also a RenderedText property to capture the text passed into the Render method so that an assertion can be made based on the value.
When you used NSubstitute, you had to tell the mock view to raise an event. But since the IView interface doesn't allow you to trigger the event, only add an event listener, NSubstitute does a workaroud, by attaching a special event handler, it actually triggers an event (I'm not familiar with NSubstitute, but I assume this is what happens):
// Code here says "attact an event handler", but NSubstitute recognizes this
// special event handler and raises the event to the "real" hanlders instead
mockView.Loaded += Raise.Event<Action>();
So when you move away from NSubstitute, you need to actually trigger the event the "correct" way from the fake view class:
public class FakeView : IView
{
private string RenderedText { get; private set; }
public event Action Loaded;
public void Render(string text)
{
renderedText = text;
}
public void RaiseLoaded() {
if (Loaded != null) Loaded();
}
}
Now you can easily trigger the events from your test:
[Test]
public void ctor_WhenViewIsLoaded_CallsViewRender_WithoutMockingFramework()
{
FakeView view = new FakeView();
Presenter p = new Presenter(fPresenter);
view.RaiseLoaded();
Assert.That(view.RenderedText, Is.EqualTo("Hello World"));
}
I have the following situation.
SomeClass has a dependency on IDiagram and Diagram implements that interface. The lifetime of SomeClass is the lifetime of the Application, however the lifetime a Diagram is shorter. Say it could change when a certain button is pressed.
Since I could not find anything satisfying on this problem I came up with the pattern depicted in the Diagram below.
The Observer of the Diagram would be aware that the Diagram can change and set the correct instance when it changes.
The Observer would implement the IDiagram interface by delegating the methods of the current Diagram instance.
SomeFactory would create new Diagrams and RaiseChanged.
SomeClass would not be aware of any of this.
Is enforcing this pattern a good idea, which downsides are there? Is there a better solution to this problem?
Example code with IDependency instead of IDiagram below:
private static void Main(string[] args)
{
var transientDependency = new TransientDependency();
var dependencyObserver = new DependecyObserver(transientDependency);
var dependencyFactory = new Factory(transientDependency);
var someClass = new SomeClass(dependencyObserver);
var someOtherClass = new SomeClass(dependencyObserver);
// Note that someClass can only be used after the dependency has been created, because the Changed event has to be invoked
dependencyFactory.CreateDependency();
}
public class DependecyObserver : IDependency
{
public DependecyObserver(TransientDependency transient)
{
transient.Changed += (s, dependency) => Dependency = dependency;
}
private Dependency Dependency { get; set; }
public void SomeMethod()
{
Dependency.SomeMethod();
}
}
public class Factory
{
private TransientDependency TransientDependency { get; }
public Factory(TransientDependency transientDependency)
{
TransientDependency = transientDependency;
}
public void CreateDependency()
{
TransientDependency.RaiseChanged(new Dependency());
}
}
public class SomeClass
{
public SomeClass(IDependency dependency)
{
dependency.SomeMethod();
}
}
public class TransientDependency : TransientInstance<Dependency> { }
public abstract class TransientInstance<T>
{
public EventHandler<T> Changed;
public void RaiseChanged(T instance)
{
Changed?.Invoke(this, instance);
}
}
public class Dependency : IDependency
{
public void SomeMethod()
{
throw new NotImplementedException();
}
}
public interface IDependency
{
void SomeMethod();
}
Is there an equivalent of JUnit's Rule in C# ? I mean a way to avoid the repetition the same [SetUp] and [TearDown] lines in several different tests. Instead of:
[SetUp]
public void SetUp()
{
myServer.connect();
}
[TearDown]
public void TearDown()
{
myServer.disconnect();
}
... put the logic in a rule that can be declared as field in several tests:
public MyRule extends ExternalResource {
#Override
protected void before() throws Throwable
{
myServer.connect();
};
#Override
protected void after()
{
myServer.disconnect();
};
};
and then
class TestClass
{
#Rule MyRule = new MyRule();
...
}
You could implement your own TestActionAttribute class that runs your before- and after-test code. If you intend to perform the same action before and after every test, you can define your custom attribute at the class declaration.
e.g.:
[MyRule] // your custom attribute - applied to all tests
public class ClassTest
{
[Test]
public void MyTest()
{
// ...
}
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class MyRuleAttribute : TestActionAttribute
{
public override void BeforeTest(TestDetails testDetails)
{
// connect
}
public override void AfterTest(TestDetails testDetails)
{
// disconnect
}
}
NUnit works well with tests inheritance, so you can create a base test class with SetUp and TearDown methods:
[TestFixture]
public class BaseTest
{
[SetUp]
public virtual void SetUpTest()
{
//...
}
[TearDown]
public virtual void TearDownTest()
{
//...
}
}
Then create a regular test class that inherits from the base class and it will reuse the SetUp and TearDown implementations:
[TestFixture]
public class RegularTest : BaseTest
{
[Test]
public virtual void MyTest()
{
//...
}
}
I'm using NUnit to test my application, which I've included a simplified version of below. I'm looking for a way to fire an event on a mock class, and check that the class under test has received it.
The application calls LogIn on the session, and, some time later, the session fires the OnLoggedIn event. I've set up a mock session, and checked that the app calls LogIn on it. Now I want to fire the OnLoggedIn event on it, and check that the app handles this event.
How can I do this?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using NUnit.Mocks;
namespace NUnitTest
{
public delegate void LoggedInDelegate();
public interface ISession
{
void LogIn(String username, String password);
event LoggedInDelegate OnLoggedIn;
}
public class App
{
private bool loggedIn = false;
private ISession sess;
public bool LoggedIn
{
get
{
return loggedIn;
}
}
public App(ISession sess)
{
this.sess = sess;
sess.OnLoggedIn += HandleOnLoggedIn;
}
public void LogIn(String username, String password)
{
sess.LogIn(username, password);
}
public void HandleOnLoggedIn()
{
loggedIn = true;
}
}
[TestFixture]
public class AppTest
{
private String USERNAME = "Username";
private String PASSWORD = "Password";
private DynamicMock mockSess;
private App app;
[SetUp]
public void TestInit()
{
// Create objects.
mockSess = new DynamicMock(typeof(ISession));
app = new App((ISession) mockSess.MockInstance);
}
[Test]
public void TestLogin()
{
mockSess.Expect("LogIn", USERNAME, PASSWORD);
app.LogIn(USERNAME, PASSWORD);
mockSess.Verify();
mockSess.Call("OnLoggedIn");
Assert.IsTrue(app.LoggedIn);
}
}
}
Try this article: https://web.archive.org/web/20110914180329/http://blog.gravityfree.ca/2007/03/raising-events-in-nmock-20.html. I didn't really get it, but I will sit down and try it out later, because I have the same problem.
I usually make an oldfashioned stub object (no mocking framework), and raise the event via a Method call in the stub. It goes something like this:
[TestFixture]
public sealed class TestStubbingEvents
{
[Test]
public void FooReceivesEventFromBar()
{
BarStub bar = new BarStub();
Foo foo = new Foo(bar);
Assert.That(foo.EventReceived, Is.False);
bar.RaiseBarEvent();
Assert.That(foo.EventReceived, Is.True);
}
}
internal class Foo
{
public bool EventReceived
{
get; set;
}
public Foo(IBar bar)
{
EventReceived = false;
bar.BarEvent += ReceiveBarEvent;
}
private void ReceiveBarEvent(object sender, EventArgs args)
{
EventReceived = true;
}
}
internal class BarStub : IBar
{
public event BarEventHandler BarEvent;
//Stub method that invokes the event
public void RaiseBarEvent()
{
BarEvent.Invoke(this, new EventArgs());
}
}
public delegate void BarEventHandler(object sender, EventArgs args);
public interface IBar
{
event BarEventHandler BarEvent;
}
This is the best I've come up with, so I am interested to see what the article in the link can produce.
Added:
Note, that the EventReceived property on the Foo class is just an example on how the event affects the object.