Coder Social home page Coder Social logo

wgnf / arrangecontext Goto Github PK

View Code? Open in Web Editor NEW
3.0 2.0 0.0 87 KB

:keyboard: .NET C#: Simple Tool to automatically initialize your system-under-test with mocked instances.

License: MIT License

C# 93.43% PowerShell 6.57%
tdd unittesting mocks mocking faking stubbing substitution dotnet semver

arrangecontext's Introduction

⌨️ ArrangeContext

GitHub license Uses SemVer 2.0.0 Latest Release Core Downloads Core
GitHub stars GitHub forks GitHub watchers

⌨️ .NET C#: Simple Tool to automatically initialize your system-under-test with mocked instances.
Inspired by NEdifis and AutoFixture

This'll turn something horrible like this:

var mock1 = new Mock<ISomeService1>();
var mock2 = new Mock<ISomeService2>();
var mock3 = new Mock<ISomeService3>();
var mock4 = new Mock<ISomeService4>();

var systemUnderTest = new SystemUnderTest(mock1, mock2, mock3, mock4);

To an even easier call like:

var systemUnderTest = new ArrangeContext<SystemUnderTest>().Build();

Additionally giving you the extra comfort of not needing to update the test-classes when you add a new parameter to your System-Under-Test:
If you add a new Parameter with ISomeService5 to your SystemUnderTest, in the "default"-approach you'd have to add a new line var mock5 = new Mock<ISomeService5>() to the arrangement of your SystemUnderTest!

🌟 Supported mocking Frameworks

Framework
Moq Latest Release Moq Downloads Moq
NSubstitute Latest Release NSubstitute Downloads NSubstitute
RhinoMocks Latest Release Rhino Mocks Downloads Rhino Mocks
FakeItEasy Latest Release FakeItEasy Downloads FakeItEasy

🌐 Features

Creating the Context

var context = new ArrangeContext<YourTestClass>();

Creating the ArrangeContext is just as easy as creating a new class, providing your System-Under-Test with as the generic type-parameter.

Build

context.Build();

This'll build the System-Under-Test with automatically mocked Constructor parameters for you, to run all the test's on this instance.

Retrieving the mocked parameters

var service1 = context.For<IService1>();
var service2 = context.For<IService2>("parameterName");

For<T> and For<T>(string parameterName) are used to retrieve the mocked instances from the ArrangeContext so you can tell them what to do and/or return when specific things are called (depending on the Framework you use obviously!).

Replacing instances

var myInstance1 = new Service1();
var myInstance2 = new Service2();

context.Use<IService1>(myInstance1);
context.Use<IService2>(myInstance2, "parameterName");

You don't like the mocked instance that was created for you? No problem! Using Use<T>() and Use<T>(string parameterName) you can replace any instance on the ArrangeContext that you like!

⌨️ Developing

To develop and work with ArrangeContext you just need to clone this Repo somewhere on your PC and then open the Solution or the complete Source-Folder (under src) with your favorite IDE. No additional tools required.

Before you can start, you should restore all NuGet-Packages using dotnet restore if that's not done for you by your IDE.

👋 Want to Contribute?

Cool! We're always welcoming anyone that wants to contribute to this project! Take a look at the Contributing Guidelines, which helps you get started. You can also look at the Open Issues for getting more info about current or upcoming tasks.

💬 Want to discuss?

If you have any questions, doubts, ideas, problems or you simply want to present your opinions and views, feel free to hop into Discussions and write about what you care about. We'd love to hear from you!

arrangecontext's People

Contributors

wgnf avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar

arrangecontext's Issues

[BUG]: Working with sealed classes with ArrangeContext.Moq does not work

Description of the bug

Scenario:
I have a (sealed) class that is a ctor parameter of the class that i want to test. Creating a context with new ArrangeContext<> is no problem.

But when i then want to replace this instance (Use<>(newInstance)) with an instance that I want to provide (because a mocking framework cannot create a mock for a (sealed) class) i get following exception:

ArrangeContext.Core.InstanceCreationFailedException: Instance-Creation failed for the Parameter settings. Please check the InnerException for more det...

ArrangeContext.Core.InstanceCreationFailedException
Instance-Creation failed for the Parameter settings. Please check the InnerException for more details.
   at ArrangeContext.Core.ArrangeContextBase`1.CreateInstance(ParameterInfo parameter)
   at ArrangeContext.Core.ArrangeContextBase`1.InitializeContextParameterFor(ParameterInfo parameter)
   at ArrangeContext.Core.ArrangeContextBase`1.InitializeContextParameters(IEnumerable`1 parameters)
   at ArrangeContext.Core.ArrangeContextBase`1.ConsiderInitialization()
   at ArrangeContext.Core.ArrangeContextBase`1.GetParameter[T]()
   at ArrangeContext.Moq.ArrangeContext`1.Use[T](T mockedInstance)
   at Liz.Core.Tests.Utils.ProvideTemporaryDirectoryTests.Get_Should_Provide_A_Temporary_Directory_Next_To_The_Target_File() in X:\Dev\git\liz\src\Core\Liz.Core.Tests\Utils\ProvideTemporaryDirectoryTests.cs:line 27

System.InvalidOperationException
There was an issue creating a mock for ExtractLicensesSettings.This is possibly due to the Type not being accessible. Consider making it internal/public and/or using [assembly:InternalsVisibleTo("DynamicProxyGenAssembly2")]!For more information refer to the InnerException of this Exception!
   at ArrangeContext.Moq.ArrangeContext`1.CreateMockedInstance(ParameterInfo parameter)
   at ArrangeContext.Core.ArrangeContextBase`1.CreateInstance(ParameterInfo parameter)

System.Reflection.TargetInvocationException
Exception has been thrown by the target of an invocation.
   at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean wrapExceptions)
   at System.Activator.CreateInstance(Type type, Boolean nonPublic, Boolean wrapExceptions)
   at System.Activator.CreateInstance(Type type, Boolean nonPublic)
   at System.Activator.CreateInstance(Type type)
   at ArrangeContext.Moq.ArrangeContext`1.CreateMockedInstance(ParameterInfo parameter)

System.NotSupportedException
Type to mock must be an interface or an abstract or non-sealed class. 
   at Moq.Extensions.ThrowIfNotMockeable(Type typeToMock)
   at Moq.Mock`1.CheckParameters()
   at Moq.Mock`1..ctor(MockBehavior behavior, Object[] args)
   at Moq.Mock`1..ctor(MockBehavior behavior)
   at Moq.Mock`1..ctor()
   at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean wrapExceptions)

... which is not very helpful when I want to replace that instance to NOT get an error like that.

Expected behavior:
The targeted parameter should be replaced with no problem, so that Build() then can be run without problems, even though the SystemUnderTest has a sealed class as it's ctor parameter.

Steps to reproduce

  1. Create a test which uses ArrangeContext.Moq to create the context
  2. Create a context for a class SystemUnderTest that has another (sealed) class Dependency as it's ctor parameter
  3. Execute Use<Dependency>(newInstance) on the created context
  4. Observce the above provided exception

Additional Information

This is because everything that is executed on the ArrangeContext runs ConsiderInitialization:

protected void ReplaceInstance(
ContextParameter parameterToReplace,
object instance,
object mockedInstance)
{
ConsiderInitialization();
var index = _contextParameters.IndexOf(parameterToReplace);
_contextParameters.Remove(parameterToReplace);

Tests & Code Coverage

Most of (all) the code isnt tested yet. To make sure everything works alright the code has to be tested.

And code coverage would be cool aswell - especially for the cool badge on the README!

Also initialize ValueTypes by default

See this line.

It currently only considers IsPrimitive Parameter-Types. But I could also initialize IsValueType Parameter-Types. I should definitely do that. It's just as easy as just adding IsValueType to the if.

Add documentation

Some documentation is needed!

  • XML Documentation Code: Core-Package
  • XML Documentation Code: Moq-Package
  • XML Documentation Code: NSubstitute-Package
  • README

Remake the current approach

I don't like the current approach with Extensions Methods and so on... This should be redone so it's better maintainable

Build-Automation

Some Build-Targets for commits are needed to run the tests, to make sure everything works.

Additionally, a Target for the Publication of the NuGet-Packages is needed (when a commit is tagged on master).

Questions:
Use Nuke or just the Action-System from GitHub?
Should all packages have the same version (and hence be published at once) or should each have its own version (with some tag-conventions to be able to publish different versions)?

More Providers!

More Providers would be cool, i guess. Having a look at AutoFixture, some good additions would be:

  • RhinoMock
  • FakeItEasy

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.