I am writing NUnit testing code for my WPF C# application. Here some of my methods having MessageBox.Show("");, but we dont know how to handle this in code.
Please help me by providing a solution.
Thanks,
You could create a kind of MessageBoxService that you could Mock in your test. An example code is:
public class ClassUnderTest
{
public IMessageBoxService MessageBoxService { get; set; }
public void SomeMethod()
{
//Some logic
MessageBoxService.Show("message");
//Some more logic
}
}
interface IMessageBoxService
{
void Show(string message);
}
public class MessageBoxService : IMessageBoxService
{
public void Show(string message)
{
MessageBox.Show("");
}
}
Then in your test you could choose to mock the public property or create the constructor to pass the mocked instance.
For example if you use Moq the test could look like this:
[Test]
public void ClassUnderTest_SomeMethod_ExpectsSomtething()
{
ClassUnderTest testClass = new ClassUnderTest();
testClass.MessageBoxService = new Mock<IMessageBoxService>().Object;
//More setup
//Action
//Assertion
}
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 learning how to do unit testing. I tried to search for how to do testing for a button click event but couldn't find an answer that I could understand.
How can I check if TextBlock_MouseDown event was raised and followed by reponse from PostMethod, which must not be null. My issue is, I can't find a way or don't know how to check TextBlock_MouseDown event using NUnit.
public partial class MainWindow : Window
{
public MainWindow(){
InitializeComponent();
}
public void TextBlock_MouseDown(object sender, MouseButtonEventArgs e){
//Check return value from PostMethod
string reponse = PostMethod("myurlhere");
}
public static String PostMethod(String val){
//Code
}
}
[TestFixture]
public class TestClass
{
[Test]
public void PostMethod_IsAlive_returnHello()
{
//ARRANGE
String url = "myurlhere";
//ACT
string response = MainWindow.PostMethod(url);
//ASSERT
Assert.AreEqual("\"Hello\"", response);
}
}
If you want to to test your UI, you should use a test library for UI-Testing.
For example FlaUI (https://github.com/Roemer/FlaUI).
NUnit is used to test your code behind. For example if you want to check if PostMethod() is returning a specific value.
If you only want to check the result of PostMethod(), outsource the method to another class and test it (MainWindow will now use OutsourcedClass.PostMethod() in its code behind).
outsourced class
public class OutsourcedClass
{
public string PostMethod(string url)
{
return url;
}
}
unit test
public class OutsourcedClassTest
{
private OutsourcedClass _Instance;
[SetUp]
public void Setup()
{
_Instance = new OutsourcedClass();
}
[Test]
public void PostMethodTest()
{
string url = "foo";
Assert.AreEqual(url, _Instance.PostMethod(url));
}
}
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"));
}
When trying to invoke a Test from a different class from where it is implemented, it does not execute the Parallelizable attribute, instead, it only executes the methods sequentially ( Alltest_2() and Alltest_1() ). Is there any way to invoke them so that they are executed in parallel?
Here's a code sample:
public class AO_Alarms_4 : AO_Alarms_3
{
[SetUp]
public void DefaultSetUp(){ }
[Test]
public void Alltest_Clases()
{
Alltest_2();
Alltest_1();
}
[TearDown]
public void DefaultTearDown() { }
}
[TestFixture]
[Parallelizable]
public class AO_Alarms_3 : AO_Alarms_2
{
public WebDriverFactory driver = new WebDriverFactory(Utils.Browser);
[SetUp]
public void login_2()
{
//code
}
[Test]
[Parallelizable]
public void Alltest_2()
{
test_2();
}
public void test_2()
{
//code
}
[TearDown]
public void teardown_2()
{
//code
}
}
[TestFixture]
[Parallelizable]
public class AO_Alarms_2
{
public WebDriverFactory driver = new WebDriverFactory(Utils.Browser);
[SetUp]
public void login_1()
{
//code
}
[Test]
[Parallelizable]
public void Alltest_1()
{
test1_1();
test1_2();
}
[Test]
public void test1_1()
{
//code
}
[Test]
public void test1_2()
{
//code
}
[TearDown]
public void teardown_1()
{
//code
}
}
You can't simply call tests yourself and expect to get any of the normal NUnit behavior around tests. For example, NUnit knows what to do when it calls a test with [Parallelizable] on it - and what it does is fairly complicated. Your own call is simply calling the method you wrote.
There is nothing to stop you from calling common methods within a given test, but the tests themselves have to be invoked by NUnit.
If you can rephrase or ask another question about what you are actually trying to accomplish here, we can probably give you some advice about alternatives.
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()
{
//...
}
}