Hello I have code like below and use xUnit. I would like to write TestClass to test my interface. Could you tell my how can I:
inject different services to test class by DependencyInjection and run test for this services.
prepare object to inject with Autofixture and AutoMoq. Before inject i would like to create services like
I want to do somethink like this :
public ServiceTestClass
{
private ISampleService sut;
public ServiceTestClass(ISampleService service) {
this.sut = service;
}
[Fact]
public MyTestMetod() {
// arrange
var fixture = new Fixture();
// act
sut.MakeOrder();
// assert
Assert(somethink);
}
}
public class SampleService : ISampleService // ande few services which implements ISampleService
{
// ISampleUow also include few IRepository
private readonly ISampleUow uow;
public SampleService(ISampleUow uow) {
this.uow = uow;
}
public void MakeOrder() {
//implementation which use uow
}
}
It isn't particularly clear what you're asking, but AutoFixture can serve as an Auto-mocking Container. The AutoMoq Glue Library is one of many extensions that enable AutoFixture to do that. Others are AutoNSubstitute, AutoFakeItEasy, etc.
This enables you to write tests like this one:
[Fact]
public void MyTest()
{
var fixture = new Fixture().Customize(new AutoMoqCustomization());
var mock = fixture.Freeze<Mock<ISampleUow>>();
var sut = fixture.Create<SampleService>();
sut.MakeOrder();
mock.Verify(uow => /* assertion expression goes here */);
}
If you combine it with the AutoFixture.Xunit2 Glue Library, you can condense it to this:
[Theory, MyAutoData]
public void MyTest([Frozen]Mock<ISampleUow> mock, SampleService sut)
{
var sut = fixture.Create<SampleService>();
sut.MakeOrder();
mock.Verify(uow => /* assertion expression goes here */);
}
Related
I am using XUnit and need to perform some action before running a test suit. so, I try to use IClassFixture feature of XUnit. but I cannot find a way to inject dependencies into the Fixture class. my code structure is such as below:
public class MyFixture
{
IDependency _dep;
public MyFixture(IDependency dep)
{
_dep = dep;
}
void DoSomeJob()
{
//// some code there
dep.DoSome();
}
}
And this is my test class code:
public class MyTest : IClassFixture<MyFixture>
{
[Fact]
public void test_my_code()
{
////simply just test the code
}
}
but when I run the test I am getting the exception
Xunit.Sdk.TestClassException Class fixture type 'MyFixture' had one or more unresolved constructor
Your Fixture class depends on IDependency dep, which has not been configured. You could use the Fixture class to setup a service provider; However it is not the best solution, as you have to end up using service locator patter such as
serviceProvider.GetRequiredService<T>()
Suggest to use xunit.di, it is an extension built into xunit framework to support constructor dependency injection, which allows us to achieve Inversion of Control (IoC) between test classes and their dependencies.
Install-Package Xunit.Di
To use xunit.di:
Install the xunit.di nuget package
Create a Setup.cs class to configure dependencies, (optional) and inherits the Xunit.Di.Setup.cs
Configure dependencies in the Setup.cs class.
Find full instructions and demos from xunit.di GET-STARTED
Your test project has the following:
Setup class that has a public IServiceProvider, which configures all the dependencies
Test class with constructor injecting the dependencies
Your Setup.cs class looks like below:
private IServiceProvider _services;
private bool _built = false;
private readonly IHostBuilder _defaultBuilder;
public Setup()
{
_defaultBuilder = Host.CreateDefaultBuilder();
}
public IServiceProvider Services => _services ?? Build();
private IServiceProvider Build()
{
if (_built)
throw new InvalidOperationException("Build can only be called once.");
_built = true;
_defaultBuilder.ConfigureServices((context, services) =>
{
services.AddSingleton<TextReaderService>();
services.AddSingleton<IDependency, DependencyImpl>();
// where DependencyImpl implements IDependency
// ... add other services needed
});
_services = _defaultBuilder.Build().Services;
return _services;
}
Then your test class looks like below:
public class MyTest
{
private readonly IDependency _dependency;
public MyTest(IDependency dependency)
{
_dependency = dependency;
}
[Fact]
public void test_my_code()
{
var result = _dependency.DoStuff();
Assert.NotNull(result);
////simply just test the code
}
}
I'm new to both unit tests, Autofac and mocks so likely, this is relatively easy, but I'm having a hard time figure it out.
I have this class SystemUnderTest with one dependency, and two methods GetValueOne and GetValueTwo.
public class SystemUnderTest : ISystemUnderTest
{
private readonly IDependency _dependency;
public SystemUnderTest(IDependency dependency)
{
_dependency = dependency;
}
public string GetValueOne()
{
return _dependency.GetValueOne();
}
public string GetValueTwo()
{
return _dependency.GetValueTwo();
}
}
public interface ISystemUnderTest
{
string GetValueOne();
string GetValueTwo();
}
These methods gets data from the dependency.
public class Dependency : IDependency
{
public string GetValueOne()
{
return "get-value-one";
}
public string GetValueTwo()
{
return "get-value-two";
}
}
public interface IDependency
{
string GetValueOne();
string GetValueTwo();
}
I'm trying to fake the data from one of the methods (the "GetValueTwo") so its returning "expected value" instead of "get-value-two" which is what the dependency normally returns.
[Fact]
public async Task Test_SystemUnderTest()
{
using (var mock = AutoMock.GetLoose())
{
// Setup
mock.Mock<IDependency>().Setup(x => x.GetValueTwo()).Returns("expected value");
// Configure
mock.Provide<IDependency, Dependency>();
// Arrange - configure the mock
var sut = mock.Create<SystemUnderTest>();
// Act
var actual_GetValueOne = sut.GetValueOne();
var actual_GetValueTwo = sut.GetValueTwo();
// Assert - assert on the mock
Assert.Equal("get-value-one", actual_GetValueOne);
Assert.Equal("expected value", actual_GetValueTwo);
}
}
The first part in my test, the Setup piece, does not seem to have any effect, and its probably because I'm doing some basic stuff wrong.
Anyone with insights on how to save my day?
The members of Dependency implementation would need to have virtual members for them to be able to be overridden when doing a partial mocked.
public class Dependency : IDependency {
public virtual string GetValueOne() {
return "get-value-one";
}
public virtual string GetValueTwo() {
return "get-value-two";
}
}
Then similar to what was suggested in another answer you would instead mock the implementation, making sure to enable it to call base members and only setup the members you need to override.
public void Test_SystemUnderTest() {
using (var mock = AutoMock.GetLoose()) {
// Setup
var dependency = mock.Mock<Dependency>();
dependency.CallBase = true;
dependency.Setup(x => x.GetValueTwo()).Returns("expected value");
// Configure
mock.Provide<IDependency>(dependency.Object);
// Arrange - configure the mock
var sut = mock.Create<SystemUnderTest>();
// Act
var actual_GetValueOne = sut.GetValueOne();
var actual_GetValueTwo = sut.GetValueTwo();
// Assert - assert on the mock
Assert.AreEqual("get-value-one", actual_GetValueOne);
Assert.AreEqual("expected value", actual_GetValueTwo);
}
}
The above passes when exercised provided that the members of the implementation that need to be mocked can be overridden (ie virtual).
Not an expert in writing unit tests, but I'm pretty sure that by using Provide with two type arguments, you overwrite the Setup part you did previously. By my understanding, the Provide method should be used to provide your own mock implementation of target interface, so using both Provide with two type arguments and Setup for the same dependency doesn't make sense.
So you can either modify the Dependency implementation's GetValueTwo to return "expected value" and use the rest of your code unmodified, or you can supply the mocked instance to the Provide method with one type argument, with both of the methods previously setup, like this:
[Fact]
public async Task Test_SystemUnderTest()
{
using (var mock = AutoMock.GetLoose())
{
var mockedDependency = mock.Mock<IDependency>();
// Setup
mockedDependency.Setup(x => x.GetValueOne()).Returns("get-value-one");
mockedDependency.Setup(x => x.GetValueTwo()).Returns("expected value");
// The following line is not even necessary
mock.Provide<IDependency>(mockedDependency.Object);
// Arrange - configure the mock
var sut = mock.Create<SystemUnderTest>();
// Act
var actual_GetValueOne = sut.GetValueOne();
var actual_GetValueTwo = sut.GetValueTwo();
// Assert - assert on the mock
Assert.Equal("get-value-one", actual_GetValueOne);
Assert.Equal("expected value", actual_GetValueTwo);
}
}
I declared a class LogManager and an interface ILogManager, and has a method LoggerError, this method use ILogger (DI) to logerror and do other things.
There is a class A (DI ILogClass ) and declare a method funA(), and funA() will use _LogManager.LoggerError("test message").
When do I unit test with mock ?
How to Verify _LogManager.LoggerError("test message") ?
If I just use ILogger in class A, I can Verify with :
loggerMock.Verify(l => l.Log(LogLevel.Error,It.IsAny<EventId>(),
It.Is<object>(o => o.ToString().Contains("test message")),null,It.IsAny<Func<object, Exception, string>>()), Times.Once);
But not support with ILogManager mock.
public class LoggerManager<TCategoryName> : ILoggerManager<TCategoryName>
{
private readonly ILogger<TCategoryName> _logger;
public LoggerManager(ILogger<TCategoryName> logger)
{
this._logger = logger;
}
public void LogError(string message, LoggerErrorType type)
{
var errorLogger = NLog.LogManager.GetLogger(loggerName);
errorLogger.Error(message);
}
}
class A
{
....DI
public void Test()
{
_loggerManager.LogError("test message")
}
}
UT:
public void TestUT()
{
var loggerMock = new Mock ILoggerManager A>>();
var service = ServiceFactory.Create<A>(loggerMock);
service.Test();
//how to Verify logerror message?
}
Your LoggerManager<TCategoryName> is just a wrapper over the ILogger<TCategoryName> and thus you can just mock ILogger<TCategoryName> and verify the same as you have already done and that should work just fine.
Though while making the actuall call to SUT you will have to dependency inject the LoggerManager<TCategoryName> accordingly
Is it possible to create a class under test with FakeItEasy, where all dependencies that are declared in the constructor are initialized automatically with fakes?
Imagine the class:
public class Inserting
{
public Inserting(
ITransactionService transactionService,
ISharedData sharedData)
{
TransactionService = transactionService;
SharedData = sharedData;
}
public ITransactionService TransactionService { get; }
public ISharedData SharedData { get; }
public void Enter()
{
TransactionService.StartTransaction();
}
}
Then I am creating all fake-objects in the test setup and construct my class under test with those fakes:
public class InsertingTest
{
private Inserting _inserting;
private ISharedData _fakeSharedData;
private ITransactionService _fakeTransactionService;
[SetUp]
public void SetUp()
{
_fakeTransactionService = A.Fake<ITransactionService>();
_fakeSharedData = A.Fake<ISharedData>();
_inserting = new Inserting(_fakeTransactionService, _fakeSharedData);
}
[Test]
public void TestEnter()
{
// Arrange
// Act
_inserting.Enter();
// Assert
A.CallTo(() => _fakeTransactionService.StartTransaction().MustHaveHappened();
}
}
But I saw in the Java-world, that when using Mockito and Dagger 2, you can do something like this:
public class PhoneDialer {
private Activity activity;
private PhoneCallListener phoneCallListener;
#Inject
public PhoneDialer(Activity activity, PhoneCallListener phoneCallListener) {
this.activity = activity;
this.phoneCallListener = phoneCallListener;
}
}
public class PhoneDialerTest {
#Rule
public MockitoRule mockitoRule = MockitoJUnit.rule();
#Mock
PhoneCallListener phoneCallListener;
#Mock
Activity activity;
#InjectMocks
PhoneDialer dialer;
#Test
public void test_dialer() throws Exception {
// Arrange
// Act
dialer.callNumber("abc");
// Assert
Mockito.verify(phoneCallListener, times(1)).startCall();
}
}
and the mocked classes are initialized automatically with fakes. Is there an equivalent procedure or function in C# with FakeItEasy?
I think you want something like
Automatically inject fakes in test fixture with FakeItEasy. You use [Fake] to mark fakes to inject and [UnderTest] to mark the production type to test.
We really should put this into the documentation.
Alternatively,
AutoFixture has an AutoFixture.AutoFakeItEasy module,
there's Autofac FakeItEasy integration, and also
Ninject FakeItEasy integration
I saw 'Automatically inject fakes in text fixture with FakeItEasy' and my initial reaction was surprise that it differed from my preconception, mainly because it needs 'intrusive' changes that attribute the test code... but perhaps that is an overreaction.
The FakeAttribute and UnderTestAttribute do force what is potentially a good structural constraint on your test (and system) design...
[FWLIW, before googling this, I had imagined the following:
containerBuilder.RegisterAsFakeCallingBaseType<SystemUnderTest>();
You can do something like this with Autofac's registration sources.
using Autofac;
using Autofac.Core;
using Autofac.Core.Activators.Delegate;
using Autofac.Core.Lifetime;
using Autofac.Core.Registration;
using FakeItEasy;
using Xunit;
public interface IDependOnSomething { }
public class IImplementThat : IDependOnSomething { }
public class CanIResolveIt
{
public CanIResolveIt(IDependOnSomething it)
{
}
}
public class FakeRegistrationSourceTest
{
[Fact]
public void BasicTest()
{
var container = new ContainerBuilder();
container.RegisterTypes<IImplementThat>().As<IDependOnSomething>();
container.RegisterSource(new FakeRegistrationSource<CanIResolveIt>());
var c = container.Build();
var theFake = c.Resolve<CanIResolveIt>();
Assert.NotNull(theFake);
}
}
public class FakeRegistrationSource<T> : IRegistrationSource
where T : class
{
public bool IsAdapterForIndividualComponents => false;
public IEnumerable<IComponentRegistration> RegistrationsFor(Service service, Func<Service, IEnumerable<IComponentRegistration>> registrationAccessor)
{
var swt = service as IServiceWithType;
if (swt == null || !typeof(T).IsAssignableFrom(swt.ServiceType)) // TODO: is this the right way around?
{
return Enumerable.Empty<IComponentRegistration>();
}
var registration = new ComponentRegistration(
Guid.NewGuid(),
new DelegateActivator(swt.ServiceType, (context, #params) =>
{
List<object> v = new List<object>();
foreach (ParameterInfo p in typeof(T).GetConstructors().Single().GetParameters())
{
v.Add(context.Resolve(p.ParameterType));
}
return A.Fake<T>(that => that.CallsBaseMethods().WithArgumentsForConstructor(v));
}),
new CurrentScopeLifetime(),
InstanceSharing.None,
InstanceOwnership.OwnedByLifetimeScope,
new[] { service },
new Dictionary<string, object>());
return new IComponentRegistration[] { registration };
}
}
Main advantage of this approach is that it knows how to instantiate fake objects subclassing classes with constructor parameters, and inheriting their default behavior, when they have a single constructor (choosing intelligently from multiple constructors would be an obvious challenge that I'm not going to tackle...)
An obvious drawback is explicit registration every time you want something faked. AutoFake and so on offer ways to overcome that with faking of just about everything by default, which might well be what you want... and you can override it if not.]
Am trying Unity IoC, after using constructor based DI.
Problem is trying to get integration tests working.
http://patrick.lioi.net/2013/06/20/streamlined-integration-tests/
"Running your integration tests should exercise as much of the real system as is reasonably possible"
Patrick above describes setting up an IoC inside the MVC Unit test project.. but I'm stuck as to how to implement
public class HomeController : Controller
{
readonly IWinterDb db;
// Unity knows that if IWinterDb interface is asked for, it will inject in a new WinterDb()
public HomeController(IWinterDb db)
{
this.db = db;
}
public ActionResult Index()
{
var stories = db.Query<Story>()
.OrderByDescending(s => s.Rating)
.Include(s => s.StoryType);
return View(stories);
}
Unit tests are fine, passing in a fake:
[TestMethod]
public void Index_GivenFake_ShouldReturn100Stories()
{
var db = new FakeWinterDb();
db.AddSet(TestData.Stories);
var controller = new HomeController(db);
var result = controller.Index() as ViewResult;
var model = result.Model as IEnumerable<Story>;
Assert.AreEqual(100, model.Count());
}
However I like integration tests which test the whole stack:
//Integration tests depend on the test data inserted in migrations
[TestClass]
public class HomeControllerTestsIntegration
{
[TestMethod]
public void Index_GivenNothing_ResultShouldNotBeNull()
{
var controller = new HomeController();
var result = controller.Index() as ViewResult;
Assert.IsNotNull(result);
}
Problem: This will not compile (as no parameterless constructor). And Unity is not being called to inject in the correct dependency for HomeController.
Unity wire up:
public static class UnityConfig
{
public static void RegisterComponents()
{
var container = new UnityContainer();
// register all your components with the container here
// it is NOT necessary to register your controllers
container.RegisterType<IWinterDb, WinterDb>();
// for authentication
container.RegisterType<AccountController>(new InjectionConstructor());
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
}
}
Edit1:
[TestMethod]
public void Index_GivenNothing_ResultShouldNotBeNull()
{
UnityConfig.RegisterComponents();
var controller = UnityConfig.container.Resolve<HomeController>();
var result = controller.Index() as ViewResult;
Assert.IsNotNull(result);
}
Making sure the singleton is there.
public static class UnityConfig
{
public static UnityContainer container;
public static void RegisterComponents()
{
container = new UnityContainer();
// register all your components with the container here
// it is NOT necessary to register your controllers
//container.RegisterType<IWinterDb, WinterDb>();
container.RegisterTypes(
AllClasses.FromLoadedAssemblies(),
WithMappings.FromMatchingInterface, // Convention of an I in front of interface name
WithName.Default
); // Default not a singleton in Unity
// for authentication
container.RegisterType<AccountController>(new InjectionConstructor());
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
}
}
Exposing Unity to the test project
You need to resolve your controller via the container for Unity to resolve dependencies for you.
It may be as simple as replacing this:
var controller = new HomeController();
with this:
var controller = container.Resolve<HomeController>();
You will obviously need to expose your container to your test class. This is something you would not normally do when wiring up your production code.