Lightinject and xUnit InjectData - c#

I'm trying to setup xUnit with the LightInject framework but cannot get the xUnit InlineDataAttribute to work. The following test code doesn't work:
public static void Configure(IServiceContainer container)
{
container.Register<FooController>();
}
[Theory, InjectData, InlineData("data")]
public void Test_GetViolations_Should_Return_A_Non_Empty_List(FooController service, string somedata)
{
Assert.NotEmpty(service.GetViolations(somedata));
}
This gives an error saying that it cannot find anything to inject for the parameter somedata. Removing the InlineDataAttribute will make the injection work. I really like the InlineData feature of xUnit so how do I get it to work with LightInject?

This has been fixed by the LightInject author. Now it's possible to do this.

Related

How to have a PerWebRequest Lifestyle in all my transient dependencies using ABP?

We're facing an issue in terms of performance in a .NET Framework 4.6.1 application that uses ABP 4.8.1. The detected issue is related to a continuous use of the dependency injector resolver with transient dependencies.
We were trying to change the "Lifestyle" from Transient to PerWebRequest, using Castle Windsor
(This is the default package that ABP uses) but if we do this we keep getting this exception:
Looks like you forgot to register the http module Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule”?
Of course we added the necessary lines, as mentioned in: https://stackoverflow.com/a/34920667/12042620
The exception was thrown when we tried with a proof of concept like this:
public class MyModule : AbpModule
{
public override void PreInitialize()
{
Database.SetInitializer(new CreateDatabaseIfNotExists<MyDbContext>());
Configuration.DefaultNameOrConnectionString = "Default";
}
public override void Initialize()
{
IocManager.IocContainer.Register(
Component
.For<MyDbContext>()
.LifestylePerWebRequest()
);
IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
}
}
I was trying to find some other possible solutions but all of them are related to .NET Core (they use 'Scoped' instead of this). Is there any way to implement this Lifestyle for all our dependencies while using ABP?
Try to register your types with LifestylePerWebRequest as seen here
https://github.com/aspnetboilerplate/aspnetboilerplate/blob/e0ded5d8702f389aa1f5947d3446f16aec845287/src/Abp.Web.Mvc/Web/Mvc/Controllers/ControllerConventionalRegistrar.cs#L11
And add this registrar to the PreInitialize of your module like here
https://github.com/aspnetboilerplate/aspnetboilerplate/blob/e0ded5d8702f389aa1f5947d3446f16aec845287/src/Abp.Web.Mvc/Web/Mvc/AbpWebMvcModule.cs#L29

Dependency service Null Reference exception in unit testing

I am trying to include Unit testing to my Xamarin PCL project.
This is what I am basically doing :
Login Page class :
public bool isUserRemembered()
{
return DependencyService.Get<IUserDefaults>().getUserRemembered();
}
public void setRememberUser(bool check)
{
DependencyService.Get<IUserDefaults>().setUserRemembered(check);
}
UnitTest class (iOS) :
[Test]
public void RememberKeyTrueTest()
{
LoginPage page = new LoginPage();
bool isRemember = true;
page.setRememberUser(isRemember);
bool value = page.isUserRemembered();
if (value)
Pass();
else
Fail();
}
I get Null Reference Exception on this line : DependencyService.Get<IUserDefaults>().setUserRemembered(check).
Will dependency service work with unit testing? Or is there any work around it?
When I use Dependency Injection in my code, I use IoC (Inversion Of Control) to handle the creation of the dependencies in my production code, and manually create my dependencies in my unit tests.
My main reason for this is that it is explicit. Often I'll be using a Mocking framework to create fake instances so I don't want the extra complexity.
A suggestion on your code under test, you have swapped a dependency to your class for a dependency on your DependencyService. I'm not saying don't use the DependencyService but you could pass in the dependency to your constructor of the class. Then your test could pass in a fake instance and the production code would use the DependencyService to get you an IUserDefaults and pass it in. That would make your class easier to test.

Any way to use Moq to imitate properties of a real-world constructor automatically?

I've got a controller with a lot of constructor injection:
public MoviesController(ISession session, IClientContext clientContext, PManager pManager, ISegmentationService segmentationService, IGeoLocator geoLocator, IBus bus)
{
_session = session;
_clientContext = clientContext;
_pManager = pManager;
_segmentationService = segmentationService;
_geoLocator = geoLocator;
_bus = bus;
}
From my understanding (just read about Mocking), I've got a lot of Mock object properties to manually set if I wish to make a comprehensive test suite based on this controller.
For one method I'm only using one service (I'd even like to automate that with little effort if possible):
public object Show(Guid id)
{
var movie = _session.Get<movie>(id);
return movie;
}
But in another there are many services being used - is there any way to set those Moq objects up quickly? I could really use some examples as I'm new to testing. It's an asp.net mvc project with webapi 1 bundled in (testing the webapi controller here)
As has been said in the comments, if you have common setup code, you can put it in a Setup method that is called automatically from your testing framework before each test. It's decorated with a Setup attribute if you're using Nunit TestInitialize if you're using MStest. If you're using XUnit then it's a bit different.
So, your class might look like this:
public class SomeTests {
Mock<ISession> _sessionMock;
Mock<IClientContext> _clientContextMock;
[Setup]
public void Setup() {
_sessionMock = new Mock<ISession>();
_clientContextMock = new Mock <IClientContext();
}
MovieController CreateSut() {
return new MovieController(_sessionMock.Object, _clientContextMock.Object, ...);
}
[Test]
public void TestSomething() {
_sessionMock.Setup(x=>...);
//...
var sut = CreateSut();
//...
}
}
If you're trying to get away from completely creating the mocks manually, then you might want to look at something like AutoFixture with AutoMoq. Which will automatically supply mock instances when creating objects that accept interfaces. AutoFixture can be quite useful, but there is a learning curve to using it effectively so you might want to look at a tutorial / quickstart.
You could also configure an IOC container to supply mock instances for your test project, although I've never gone down that route myself.
For your example, you only need to mock the session, and can leave all the other dependencies null, since their behaviour should be irrelevant to the behaviour you are testing:
Mock<ISession> mockSession = new Mock<ISesssion>();
MoviesController controller = new MoviesController(mockSession.Object, null,null,null,null,null);
There is no need for you to set up any mocks other than the ones you need for this particular test

Why does unit test fail on first run?

I have 7 unit tests which fail when I run all tests from Solution level or from the test runner, but, when I run the tests from project level or from the project within the test runner they succeed.
I am trying to test that I can resolve an item from a Castle Windsor container once they have been installed.
[TestFixture]
public class Having_installed_the_request_processors
{
private IWindsorContainer _container;
[SetUp]
public void Setup()
{
_container = new WindsorContainer();
_container.Install(FromAssembly.Containing<RequestProcessorInstaller>());
}
[TearDown]
public void Teardown()
{
((WindsorContainer)this._container).Dispose();
_container = null;
}
[Test]
public void can_resolve_the_job_status_request_processor()
{
Assert.That(_container.Resolve<IJobStatusRequestProcessor>(), Is.Not.Null);
}
}
This is the error returned:
SetUp : Castle.MicroKernel.SubSystems.Conversion.ConverterException : Could not convert string 'Castle.Services.Logging.Log4netIntegration.Log4netFactory,Castle.Services.Logging.Log4netIntegration,Version=3.3.0.0, Culture=neutral,PublicKeyToken=407dd0808d44fbdc' to a type. Assembly was not found. Make sure it was deployed and the name was not mistyped.
As far as I can see the code in my test project is the same as my production code (which appears to function as expected).
Do you see any issues with the above?
Why does the test succeed in the aforementioned way?
I determined that this was due to the way in which the projects in the solution referenced each other, by changing the direction of some references it resolved the issue - thank you for looking

Unit Test with Ninject Instantiate

I'm trying to test my service using ninject and an unit test project with visual studio 2012. My inject works ok on my controllers, but when I try to do the same in the unit test class I get an Exception.
System.NullReferenceException: Object reference not set to an instance of an object.
namespace Trex.UnitTests
{
[TestClass]
public class GiftServiceTests
{
private IGiftService _giftService;
public void GiftServiceTest(IGiftService giftService)
{
_giftService = giftService;
}
[TestMethod]
public void AddGift()
{
var list = _gift.FindAll(); <--- this line throw an exception
}
}
}
I think there is something wrong with the injection but I dont get it.
It looks to me like a typo of _giftService. In addition, attribute [TestInitialize] needs to be used in your constructor.
Try the following code by placing the correct service name _giftService - that your code is injecting instead:
var list = __giftService.FindAll();
Edit: Unit testing should be done without Ninject. Just create an instance of the object under test and inject a mock for every dependency manually.
Here is a sample with [TestInitialize]:
The unit test must have a default constructor:
[TestClass]
public class TestControllersHomeController
{
private HomeController _sut;
[TestInitialize]
public void MyTestInitialize()
{
var kernel = NinjectWebCommon.CreatePublicKernel();
_sut = kernel.Resolve<HomeController>();
}
[TestMethod]
public void TestIndex()
{
var result = _sut.Index();
Assert.IsNotNull(result);
}
}
The only way dependency injection is able to call your constructor and fill it with a parameter that has a value is if the dependency injection kernel is the one that instantiates your class.
In your case, MSTest is instantiating your test class, so Ninject does not have a chance to call your constructor.
To be honest, you are going about this the wrong way. You will battle MSTest if you pursue this further to try to get Ninject (or any other DI framework) to instantiate your test classes.
I would recommend you use 'new' to instantiate the class under test (_giftService = new GiftService();). If that class has dependencies in its constructor, use a mocking framework to pass in mocked version of those dependencies. This way you isolate your unit tests to only the functionality of the class under test.
_gift is null. Your variable is _giftService. You also should use the [TestInitialize] attribute for your constructor.
Extra tip:
You shouldn't create any dependencies in your unit test. So the giftService which you want to use should be a mock or a stub.

Categories