Need simple example of FitNesse SetUpFixture under .NET - c#

I've been trying to implement FitNesse tests for our C# application. I'm using the latest FitNesse jar and the fitSharp .NET 2.2 4.0 libraries.
I have been able to successfully use scenarios using Slim. However, in the interests of making tests that are more legible to a non-technical audience, I'm interested in implementing DoFixtures, and I surmise I'll need SetUpFixtures to create common data conditions for tests.
I can't seem to get the data I set up into the DoFixture instance, though. I've looked at several resources (Gojko's book chief among them), but none seem to talk about this concept in isolation. Attaching Visual Studio as a debugger to test runs hasn't yielded any insight. I could really use a trivial example to analyze and build upon.
Would someone be willing to share an example that includes just:
A SetUpFixture class that sets up some data
A DoFixture class that uses the data from the SetUpFixture
Wiki syntax to invoke them?

Looks like SetUp was not called. Use Debugger.Launch() for debug
Update:
!|BirdCall|
|birdName|noise|
|duck|quack|
public class SkylarkBunting : fitlibrary.DoFixture
{
public BirdCall BirdCall;
public SkylarkBunting(BirdCall birdCall)
{
BirdCall = birdCall;
}
public string GetCall()
{
return BirdCall.Noise;
}
public string GetName()
{
return BirdCall.BirdName;
}
}

I've got a partial answer.
Using these classes:
public class BirdCall : fitlibrary.SetUpFixture
{
public void BirdNameNoise(string birdName, string noise)
{
BirdName = birdName;
Noise = noise;
}
public string BirdName;
public string Noise;
public override string ToString()
{
return string.Format("BirdCall: {0}, {1}", BirdName, Noise);
}
}
public class SkylarkBunting : fitlibrary.DoFixture
{
public BirdCall BirdCall;
public string Call;
public Fixture CryOut()
{
BirdCall = new BirdCall();
Call = BirdCall.Noise;
return BirdCall;
}
public string GetCall()
{
return BirdCall.Noise;
}
public string GetName()
{
return BirdCall.BirdName;
}
}
and this Wiki markup:
!define TEST_RUNNER {C:\temp\fitsharp\Runner.exe}
!define COMMAND_PATTERN {%m -r fitnesse.fitserver.FitServer,c:\temp\fitsharp\fit.dll %p}
!path C:\temp\FitNesseIntegration\bin\Debug\FitnesseIntegration.dll
!|import|
|FitnesseIntegration|
!|FitNesseIntegration.Skylark.SkylarkBunting|
!3 Testing getting data from a setup fixture into a do fixture
!|cry out|
|bird name|noise|
|Tweetie|Caw!|
|check|call||
|check|get call||
|check|get name||
|check|bird call||
I get:
|check|call|null|
|check|get call|Caw!|
|check|get name|Tweetie|
|check|bird call|BirdCall: Tweetie, Caw!|
This is good, I have variables in the DoFixture that were populated by executing the SetUpFixture with values injected by FitNesse via the page.
I'd still like to know why Call returns null, though.

Related

Unit test for void method with Interface as parameter

New to Unit testing, I have below sample code and I want to create a unit test for this , Please suggest what should i do to create a unit test for this ? any link or pointers would be helpful to start
public class UserNotification : Work
{
public override void Execute(IWorkContext iwc)
{
throw new InvalidWorkException($"some message:{iwc.Name} and :{iwc.Dept}");
}
}
Edit: using MSTest for Unit testing
First, you need a test project alongside with your regular project.
You can pick from these three:
MSTest
nUnit
xUnit
All of these should have a project template in VS2022.
xUnit is a popular one, so let's pick that. The usual naming convention for test projects is YourProject.Tests. Rename UnitTest1.cs class to UserNotificationTests.cs.
As simple as it gets, you can now start writing your tests. In xUnit, a method with [Fact] attribute is a test method.
using Xunit;
namespace MyProject.Tests
{
public class UserNotificationTests
{
[Fact]
public void Execute_Should_Throw_InvalidWorkException_With_Message()
{
}
}
}
Don't think these methods as the methods in the code, naming should be close to English sentences and should reveal the intent as a regular sentence.
Classic approach to unit testing has three phases:
Arrange: Take instances of your objects, set your expected output, mock dependencies, make them ready.
Act: Call the actual action you want to test.
Assert: Check if how your actual output relates to your expected output.
Let's start with arranging.
We need a new instance of UserNotification class so we can call Execute().
We need any dummy IWorkContext object so we can pass it. We'll use NSubstitute library for that.
// Don't forget to add using NSubstitute
// Arrange
var userNotification = new UserNotification();
var workContext = Substitute.For<IWorkContext>();
workContext.Name = "testName";
workContext.Dept = "testDept";
Now you act, and invoke your method:
// Act
Action act = () => userNotification.Execute(workContext);
And lastly we assert. I highly recommend FluentAssertations library for asserting.
// Assert
act.Should().Throw<InvalidWorkException>()
.WithMessage($"some message:{workContext.Name} and :{workContext.Dept}");
Navigate to View > Test Explorer and run your tests, you should see something similar to this:
Congratulations, you wrote your first unit test.
Here's the final version of your test code:
using FluentAssertions;
using NSubstitute;
using System;
using Xunit;
namespace MyProject.Tests
{
public class UserNotificationTests
{
[Fact]
public void Execute_Should_Throw_InvalidWorkException_With_Message()
{
// Arrange
var userNotification = new UserNotification();
var workContext = Substitute.For<IWorkContext>();
workContext.Name = "testName";
workContext.Dept = "testDept";
// Act
Action act = () => userNotification.Execute(workContext);
// Assert
act.Should().Throw<InvalidWorkException>()
.WithMessage($"some message:{workContext.Name} and :{workContext.Dept}");
}
}
public class UserNotification : Work
{
public override void Execute(IWorkContext iwc)
{
throw new InvalidWorkException($"some message:{iwc.Name} and :{iwc.Dept}");
}
}
public abstract class Work
{
public virtual void Execute(IWorkContext iwc) { }
}
public interface IWorkContext
{
public string Name { get; set; }
public string Dept { get; set; }
}
public class InvalidWorkException : System.Exception
{
public InvalidWorkException() { }
public InvalidWorkException(string message) : base(message) { }
public InvalidWorkException(string message, System.Exception inner) : base(message, inner) { }
protected InvalidWorkException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
}
}
Writing tests feels a lot different than writing regular code. But in time you'll get the hang of it. How to mock, how to act, how to assert, these may vary depending on what you are testing. The main point is to isolate the main thing you want to unit test, and mock the rest.
Good luck!
Because your title mentions specifically that you're trying to test a method with a void return type; I infer that you've already been testing methods with actual return values, and therefore that you already have a test project and know how to run a test once it is written. If not; the answer written by Mithgroth is a good explanation on how to get started on testing in general.
Your test is defined by the behavior that you wish to test. Your snippet has no behavior, which makes it hard to give you a concrete answer.
I've opted to rewrite your example:
public class UserNotification : Work
{
public override void Execute(IWorkContext iwc)
{
var splines = iwc.GetSplines();
iwc.Reticulate(splines);
}
}
Now we have some behavior that we want to test. The test goal is to answer the following question:
When calling Execute, does UserNotification fetch the needed splines and reticulate them?
When unit testing, you want to mock all other things. In this case, the IWorkContext is an external dependency, so it should be mocked. Mocking the work context allows us to easily configure the mock to help with the testing. When we run the test, we will pass an IWorkContext object which acts as a spy. In essence, this mocked object will:
... have been set up to return a very specific set of splines, one that we chose for the test's purpose.
... secretly record any calls made to the Reticulate method, and tracks the parameters that were passed into it.
Before we get into the nitty gritty on how to mock, we can already outline how our test is going to go:
[Test]
public void ReticulatesTheContextSplines()
{
// Arrange
IWorkContext mockedContext = ...; // This comes later
UserNotification userNotification = new UserNotification();
// Act
userNotification.Execute(mockedContext);
// Assert
// Confirm that Reticulate() was called
// Confirm that Reticulate() was given the result from `GetSplines()`
}
There's your basic unit test. All that's left is to create our mock.
You can write this yourself if you want. Simply create a new class that implements IWorkContext, and give it some more public properties/methods to help you keep track of things. A very simple example would be:
public class MockedWorkContext : IWorkContext
{
// Allows the test to set the returned result
public IEnumerable<Spline> Splines { get; set; }
// History of arguments used for calls made to Reticulate.
// Each call will add an entry to the list.
public List<IEnumerable<Spline>> ReticulateArguments { get; private set; } = new List<IEnumerable<Spline>>();
public IEnumerable<Spline> GetSplines()
{
// Returns the preset splines that the test configured
return this.Splines;
}
// Mocked implementation of Reticulate()
public void Reticulate(IEnumerable<Spline> splines)
{
// Does nothing except record what you passed into it
this.ReticulateArguments.Add(splines);
}
}
This is a very simplified implementation, but it gets the job done. The test will now look like this:
[Test]
public void ReticulatesTheContextSplines()
{
// Arrange
IEnumerable<Spline> splines = new List<Spline>() { new Spline(), new Spline() }; // Just create some items here, it's random test data.
IWorkContext mockedContext = new MockedWorkContext();
mockedContext.Splines = splines;
UserNotification userNotification = new UserNotification();
// Act
userNotification.Execute(mockedContext);
// Assert - Confirm that Reticulate() was called
mockedContext.ReticulateArguments.Should().HaveCount(1);
// Confirm that Reticulate() was given the result from `GetSplines()`
mockedContext.ReticulateArguments[0].Should().BeEquivalentTo(splines);
}
This test now exactly tests the behavior of your method. It uses the mocked context as a spy to report on what your unit under test (i.e. UserNotification) does with the context that you pass into it.
Note that I am using FluentAssertions here, as I find it the most easily readable syntax. Feel free to use your own assertion logic.
While you can write your own mocks; there are mocking libraries that help cut down on the boilerplating. Moq and NSubstitute are the two biggest favorites as far as I'm aware. I personally prefer NSubstitute's syntax; but both get the job done equally well.
If you want to use nunit the documentation with example is pretty easy to follow, link below.
Nunit documentation
And I think all other unit test framework have something similar to this.
[Test]
public void Execute_WhenCalled_ThrowArgumentException()
{
//Initialize an instance of IWorkContext
var iwc = new WorkContext();
//or use a Mock object, later on in assert use
//userNotification.Execute(iwc.Object)
var iwc = new Mock<IWorkContext>();
var userNotification = new UserNotification();
Assert.Throws(typeof(InvalidWorkException), () =>
{
userNotification.Execute(iwc)
});
}

xUnit class constructor should get arguments passed from theory test methods

On the xUnit website it says the following about constructor:
xUnit.net creates a new instance of the test class for every test that
is run, so any code which is placed into the constructor of the test
class will be run for every single test. This makes the constructor a
convenient place to put reusable context setup code where you want to
share the code without sharing object instances (meaning, you get a
clean copy of the context object(s) for every test that is run).
I have the following code:
public class ProfilePageTest
{
public ProfilePageTest(Role role)
{
AuthRepository.Login(role)
}
[Theory]
[Roles(Role.Editor, Role.Viewer)]
public void OpenProfilePageTest(Role role)
{
var profile = GetPage<ProfilePage>();
profile.GoTo();
profile.IsAt();
}
}
Is it possible to pass the role from the theory attribute to the constructor, so I don't have to do AuthRepository.Login(role) in every test method that I have.
No, that's not possible. The constructor will be run before anything else, as with any constructor you're used to. I don't see the harm in calling AuthRepository.Login(role) in every test though, because it's a single line of code.
This is quite an excellent blog post about the different ways you can pass data into xUnit tests, but all of them are passing in data to individual methods (tests) rather than in the constructor.
If you are looking to set something up for multiple tests you should have a look int IClassFixture
Quick run down, you setup a class with the shared data:
public class DatabaseFixture : IDisposable
{
public DatabaseFixture()
{
Db = new SqlConnection("MyConnectionString");
// ... initialize data in the test database ...
}
public void Dispose()
{
// ... clean up test data from the database ...
}
public SqlConnection Db { get; private set; }
}
And then in your tests you can "inject" the class (along with the data) into the test class:
public class MyDatabaseTests : IClassFixture<DatabaseFixture>
{
DatabaseFixture fixture;
public MyDatabaseTests(DatabaseFixture fixture)
{
this.fixture = fixture;
}
// ... write tests, using fixture.Db to get access to the SQL Server ...
}

In a C# method, how do I determine (externally) which methods use a field/property

I want to be able to determine the impact of making a change to a Service. In other words, given the following C# example class, I need to be able to determine if I change MyServiceWithConfig that I:
will impact the route /feature/my-route-with-config
will not impact the route /feature/my-route
[RoutePrefix("feature")]
public sealed class MyWebApiController : ApiController
{
public MyWebApiController()
: this(
new MyService(),
new MyServiceWithConfig(StaticClass.Configuration))
{
// noop
}
private MyWebApiController(
MyService myService,
MyServiceWithConfig myServiceWithConfig)
{
this.MyServiceInstance = myService;
this.MyServiceWithConfigInstance = myServiceWithConfig;
}
private MyService MyServiceInstance { get; }
private MyServiceWithConfig MyServiceWithConfigInstance { get; }
[HttpGet,
Route("my-route")]
public async Task<object> Get()
{
return await this.MyServiceInstance.DoWork();
}
[HttpGet,
Route("my-route-with-config")]
public async Task<object> GetWithConfig()
{
return await this.MyServiceWithConfigInstance.DoWork();
}
}
What I have done so far (using reflection in PowerShell 5)
Find all Types that have a base class of ApiController
Of those types I know
If they have a private field or property of type MyServiceWithConfig
Which methods are routes and what those actual routes are
What I am not able to determine how to do:
- Determine that only one of these routes actually references this.MyServiceWithConfigInstance
From what I've read in other posts - it does not look like I can determine usage of a field using reflection. Is this something that I can use another tool to do? It has to be something I can automate because I need it to scan thousands of classes and it isn't practical to process one class at a time.
Is this something that I can leverage Roslyn for?
Thanks!
Note: I can post the PowerShell, but that doesn't seem to be helpful as it is over 100 lines so far.

Mocking HttpContext.server.MapPath in ASP.NET unit testing

I have working in unit testing in ASP.Net web application, now I have accessing my constructor in the model file to test which has Server.MapPath code for uploading my XMLfile, when try to testing this i get error, because the HttpContext is null so i have to mocking Server.MapPath.
I have searched lot but every samples given only for Asp.NET MVC but I have working in ASP.NET. so please help in ASP.NET to solve this issue.
My code is given below.
public class NugetPlatformModel
{
public bool IsHavingLicense { get; set; }
public List<PlatformProducts> PlatformProduct = new List<PlatformProducts>();
public NugetPlatformModel()
{
var xmldoc = new XmlDocument();
mldoc.Load(HttpContext.Current.Server.MapPath(#"~\Content\PlatformProducts.xml"));
}
}
And my unit testing code
[Test]
public void Account_UnlicensedCustomerIdentity_IsStudioLicenseAndIshavinglicenseFalse()
{
//Act
NugetPlatformModel nugetPlatformModel = new NugetPlatformModel();
//Assert
AssertEquals(false, nugetPlatformModel.IsHavingLicense);
}
This is typical with code that calls static methods, it's very difficult to test while preserving separation of concern and avoiding tight coupling. Here is a generic approach to test and mock "untestable code": write a "facade wrapper" to it.
Create a wrapper for these methods. A simple class that contains methods named sensibly, and only delegates to the untestable calls (typically static calls)
Create an interface to that wrapper class
Instead of directly calling the untestable methods in your client code, use the wrapper (dependency-injected using the interface provided in step 2) and call normal methods on it.
In your unit-test, mock the wrapper with the behaviour you want.
This approach effectively reduces the coupling and separates the concerns that need to be separated. Of course, you still can't test the behaviour of the wrapper itself, but if it's simple enough (only delegating to the original calls) then it's not as big a problem.
Update:
Using shims to isolate your application from other assemblies for unit testing
Shim types are one of two technologies that the Microsoft Fakes Framework uses to let you easily isolate components under test from the environment. Shims divert calls to specific methods to code that you write as part of your test. Many methods return different results dependent on external conditions, but a shim is under the control of your test and can return consistent results at every call. This makes your tests much easier to write.
Use shims to isolate your code from assemblies that are not part of your solution. To isolate components of your solution from each other, we recommend that you use stubs.
How already answered, you should decouple your system
public class NugetPlatformModel
{
public bool IsHavingLicense { get; set; }
public List<PlatformProducts> PlatformProduct = new List<PlatformProducts>();
public NugetPlatformModel(IPlatformProductProvider provider)
{
var xmldoc = new XmlDocument();
//System.Web.HttpContext.Current.Server.MapPath(#"~\Content\PlatformProducts.xml")
xmldoc.Load(provider.Filepath);
}
public interface IPlatformProductProvider
{
string Filepath { get; }
}
public class PlatformProductProvider: IPlatformProductProvider
{
string _filepath;
public string Filepath
{
get { return _filepath; }
set { _filepath = value;}
}
public PlatformProductProvider(string path)
{
_filepath = path;
}
}
}
And your test could be:
[Test]
public void Account_UnlicensedCustomerIdentity_IsStudioLicenseAndIshavinglicenseFalse()
{
//Arrange
// using Moq
//var mock = new Mock<IPlatformProductProvider>();
//IPlatformProductProvider provider = mock.Object;
//provider.Filepath = "pippo.xml";
// otherwise
var provider = new PlatformProductProvider("pippo.xml");
//Act
NugetPlatformModel nugetPlatformModel = new NugetPlatformModel(provider);
//Assert
AssertEquals(false, nugetPlatformModel.IsHavingLicense);
}
If you can't modify the source code, try using shims (https://msdn.microsoft.com/en-us/library/hh549176.aspx).

Limit Ninject.MockingKernel to mocking classes in my own namespaces only

I've just switched to using the NInject.MockingKernel extension for my tests (NSubstitute).
However, it makes very hard to run my Web API integration tests because it will return mocks for all Web API interfaces also.
Can I automatically limit its application only to namespaces of my own?
I don't see how that is possible out of the box. Although it's not very hard to create such a kernel on your own.
This sample is of course very minimalistic though, but it should show you how it could be done. Or maybe there is someone with more knowledge of the Ninject internals.
public class NamespaceFilteringMockMissingBindingsResolver : MockMissingBindingResolver
{
public NamespaceFilteringMockMissingBindingsResolver(IMockProviderCallbackProvider mockProviderCallbackProvider)
: base(mockProviderCallbackProvider)
{
}
protected override bool TypeIsInterfaceOrAbstract(Type service)
{
return base.TypeIsInterfaceOrAbstract(service) && service.Namespace != null && service.Namespace.StartsWith("YourNamespace");
}
}
public class CustomNSubstituteMockingKernel : NSubstituteMockingKernel
{
public CustomNSubstituteMockingKernel()
{
this.AddComponents();
}
public CustomNSubstituteMockingKernel(INinjectSettings settings, params INinjectModule[] modules)
: base(settings, modules)
{
this.AddComponents();
}
private new void AddComponents()
{
this.Components.RemoveAll<IMissingBindingResolver>();
this.Components.Add<IMissingBindingResolver, SingletonSelfBindingResolver>();
this.Components.Add<IMissingBindingResolver, NamespaceFilteringMockMissingBindingsResolver>();
}
}
Update
You are right, you don't need to create your own kernel. You can also do it like this.
var kernel = new NSubstituteMockingKernel();
kernel.Components.RemoveAll<IMissingBindingResolver>();
kernel.Components.Add<IMissingBindingResolver, SingletonSelfBindingResolver>();
kernel.Components.Add<IMissingBindingResolver, NamespaceFilteringMockMissingBindingsResolver>();
Creating your own kernel might just be more handy than always writing those extra lines. Or you create some kind of factory method.

Categories