Shown below are the class and the method in the test class. The test method is for testing during the state that a monitoring request is published. The expected action is that the handler is called inside the FzrteMonitoringService class.
Here, I am trying to verify whether the handler for the monitoringRequestGenerated event is called inside the FzrteMonitoringService class. But the problem is that the class Dependency is a dependency, and I trying to figure out how to write the FzrteMonitoringService class to avoid such a dependency. The Dependency class is a class that works with MEF to resolve instances exported with the Export attribute. An architect was responsible for its design. Replacing the Dependency class with a TestDependency class for tests seems like an idea, but how would it create instances?
[ImportingConstructor]
public FzrteMonitoringService(IEventAggregator inEventAggregator)
{
_eventAggregator = inEventAggregator;
_monitoringRequestExecutor = Dependency.Resolve<IFzrteMonitoringRequestResponseHandler>();
WatchedPorts = new List<string>();
FailedAddWatchRequests = new List<MonitoringRequest>();
_monitoringRequests = new ConcurrentQueue<FzrteMonitoringRequest>();
//subsription for monitoring requests on the UI thread to limit the user
//from generating meaningless requests
_eventAggregator.GetEvent<MonitoringRequestGenerated>()
.Subscribe(FilterEventType, ThreadOption.UIThread, true);
}
[Test]
[Category("Simple Basic Tests")]
public void SubscribesToMonitoringRequets_requestPublished_FilterEventTypeCalled()
{
//mock of event aggregator and the request event dependencies of monitoring service
var mockEventAggregator = new Mock<IEventAggregator>();
var mockMonitoringRequestedEvent = new Mock<MonitoringRequestGenerated>();
mockEventAggregator.Setup(x => x.GetEvent<MonitoringRequestGenerated>())
.Returns(mockMonitoringRequestedEvent.Object);
Action <List<MonitoringRequest>> callbackMethod = null;
mockMonitoringRequestedEvent.Setup(x => x.Subscribe(
It.IsAny<Action<List<MonitoringRequest>>>(),
It.IsAny<ThreadOption>(),
It.IsAny<bool>(),
It.IsAny<Predicate<List<MonitoringRequest>>>())).
Callback<Action<List<MonitoringRequest>>,
ThreadOption,
bool,
Predicate<List<MonitoringRequest>>>((a, t, b, p) => callbackMethod = a);
var testFzrteMonitoringService = new FzrteMonitoringService(mockEventAggregator.Object);
//use the actual event aggregator to publish
var mockMonitoringRequestEventPayload = new Mock<List<MonitoringRequest>>();
mockEventAggregator.Object.GetEvent<MonitoringRequestGenerated>().Publish(mockMonitoringRequestEventPayload.Object);
mockMonitoringRequestedEvent.Verify(x => x.Subscribe(testFzrteMonitoringService.FilterEventType));
}
It's not really clear what exactly you're trying to test, looking on a code you've provided, but I'll try to address your question.
The main problem with Dependency class is that it's static (or probably its Resolve<> method). You should try to abstract it via introducing IDependency interface
public interface IDependency
{
T Resolve<T>();
}
so you can inject it into your service and then mock it in your tests.
After this simple refactoring your service's constructor will look like this:
[ImportingConstructor]
public FzrteMonitoringService(
IEventAggregator inEventAggregator,
IDependency dependency)
{
_eventAggregator = inEventAggregator;
_dependency = dependency;
_monitoringRequestExecutor = dependency.Resolve<IFzrteMonitoringRequestResponseHandler>();
WatchedPorts = new List<string>();
_monitoringRequests = new ConcurrentQueue<FzrteMonitoringRequest>();
//subsription for monitoring requests on the UI thread to limit the user
//from generating meaningless requests
_eventAggregator.GetEvent<MonitoringRequestGenerated>()
.Subscribe(this.FilterEventType, ThreadOption.UIThread, true);
}
and your test:
[Test]
[Category("Simple Basic Tests")]
public void SubscribesToMonitoringRequets_requestPublished_FilterEventTypeCalled()
{
//mock of event aggregator and the request event dependencies of monitoring service
var mockEventAggregator = new Mock<IEventAggregator>();
var mockMonitoringRequestedEvent = new Mock<MonitoringRequestGenerated>();
var mockDependecy = new Mock<IDependency>();
mockEventAggregator.Setup(x => x.GetEvent<MonitoringRequestGenerated>())
.Returns(mockMonitoringRequestedEvent.Object);
Action<List<MonitoringRequest>> callbackMethod = null;
mockMonitoringRequestedEvent
.Setup(
x => x.Subscribe(
It.IsAny<Action<List<MonitoringRequest>>>(),
It.IsAny<ThreadOption>(),
It.IsAny<bool>(),
It.IsAny<Predicate<List<MonitoringRequest>>>()))
.Callback<Action<List<MonitoringRequest>>, ThreadOption, bool, Predicate<List<MonitoringRequest>>>(
(a, t, b, p) => callbackMethod = a);
var testFzrteMonitoringService = new FzrteMonitoringService(
mockEventAggregator.Object, mockDependecy.Object);
//use the actual event aggregator to publish
var mockMonitoringRequestEventPayload = new Mock<List<MonitoringRequest>>();
mockEventAggregator.Object
.GetEvent<MonitoringRequestGenerated>()
.Publish(mockMonitoringRequestEventPayload.Object);
mockMonitoringRequestedEvent.Verify(
x => x.Subscribe(testFzrteMonitoringService.FilterEventType));
}
Though it may not work properly, but the main idea is there.
Related
I'm using Autofac with ASP.NET Core.
My dependency is a Reporter:
public class Reporter {
public Reporter (bool doLogging) { DoLogging = doLogging ; }
public string DoLogging { get; set; }
// other stuff
}
I need to use it like this:
public class Foo
{
public Foo(Func<bool, Reporter> reporterFactory) { _reporterFactory = reporterFactory; }
private readonly Func<bool, Reporter> _reporterFactory;
}
And I want it to resolve like this:
_reporterFactory(false) ---> equivalent to ---> new Reporter(false)
_reporterFactory(true) ---> equivalent to ---> new Reporter(true)
I want the same instance per request (i.e. Autofac's InstancePerLifetimeScope), for the same bool parameter. When I call _reporterFactory(false) multiple times, I want the same instance. And when I call _reporterFactory(true) multiple times, I want the same instance. But those two instances must be different to each other.
So I register it like this:
builder
.Register<Reporter>((c, p) => p.TypedAs<bool>() ? new Reporter(true): new Person(false))
.As<Reporter>()
.InstancePerLifetimeScope(); // gives "per HTTP request", which is what I need
However, when I resolve I get the same instances regardless of the bool argument:
var reporter = _reporterFactory(false);
var reporterWithLogging = _reporterFactory(true);
Assert.That(reporter, Is.Not.SameAs(reporterWithLogging)); // FAIL!
The documentation for "Parameterized Instantiation" says
resolve the object more than once, you will get the same object instance every time regardless of the different parameters you pass in. Just passing different parameters will not break the respect for the lifetime scope.
Which explains the behavior. So how do I register it correctly?
As mentioned in comments, you could use keyed services to achieve your goal:
builder.Register(c => new Reporter(true)).Keyed<IReporter>(true).InstancePerLifetimeScope();
builder.Register(c => new Reporter(false)).Keyed<IReporter>(false).InstancePerLifetimeScope();
The thing is, if you want to inject it to another class, you would have to inject it with IIndex<bool, IReporter>:
public class Foo
{
public Foo(IIndex<bool, IReporter> reporters)
{
var withLogging = reporters[true];
var withoutLogging = reporters[false];
}
}
IIndex is Autofac's interface, which makes your component tight coupled with the container, and this may not be desirable. To avoid this, you could additionally register the factory, like this:
builder.Register<Func<bool, IReporter>>((c,p) => withLogging => c.ResolveKeyed<IReporter>(withLogging)).InstancePerLifetimeScope();
public class Foo
{
public Foo(Func<bool, IReporter> reporters)
{
var withLogging = reporters(true);
var withoutLogging = reporters(false);
}
}
Now you have the working solution without coupling to the container itself.
New to unit testing. I have a WPF client app hooked into a WCF service via basicHttpbinding. Everything works great. I'm using simple constructor Dependency Injection in my viewModel, passing in an IServiceChannel which I then call me service methods on e.g:
IMyserviceChannel = MyService;
public MyViewModel(IMyServiceChannel myService)
{
this.MyService = myService;
}
Private void GetPerson()
{
var selectedPerson = MyService.GetSelectedPerson();
}
I have then added an MS Test project in the client app and I'm trying to use Moq to mock my service:
[TestMethod]
public void GetArticleBody_Test_Valid()
{
// Create channel mock
Mock<IIsesServiceChannel> channelMock = new Mock<IIsesServiceChannel>(MockBehavior.Strict);
// setup the mock to expect the Reverse method to be called
channelMock.Setup(c => c.GetArticleBody(1010000008)).Returns("110,956 bo/d, 1.42 Bcfg/d and 4,900 bc/d. ");
// create string helper and invoke the Reverse method
ArticleDataGridViewModel articleDataGridViewModel = new ArticleDataGridViewModel(channelMock.Object);
string result = channelMock.GetArticleBody(1010000008);
//Assert.AreEqual("cba", result);
//verify that the method was called on the mock
channelMock.Verify(c => c.GetArticleBody(1010000008), Times.Once());
}
The test is failing with a System.NullReferenceException. Object reference not set to an instance of an object. at the method invocation here:
string result = articleDataGridViewModel.IsesService.GetArticleBody(1010000008);
so I'm wandering whether this is the best way to approach or am I better somehow mocking an isolated part of the viewModel which is applicable to the test?
The NullReferenceException is mybe thrown because you use MockBehavior.Strict. The documentation says:
Causes this mock to always throw an exception for invocations that don't have a corresponding setup.
Maybe the constructor of ArticleDataGridViewModel calls other methods of the service which you haven't set up.
Another issue is, that you are calling the mocked method directly. Instead you should call a method of your view model, which calls this method.
[TestMethod]
public void GetArticleBody_Test_Valid()
{
// Create channel mock
Mock<IIsesServiceChannel> channelMock = new Mock<IIsesServiceChannel>();
// setup the mock to expect the Reverse method to be called
channelMock.Setup(c => c.GetArticleBody(1010000008)).Returns("110,956 bo/d, 1.42 Bcfg/d and 4,900 bc/d. ");
// create string helper and invoke the Reverse method
ArticleDataGridViewModel articleDataGridViewModel = new ArticleDataGridViewModel(channelMock.Object);
string result = articleDataGridViewModel.MethodThatCallsService();
//Assert.AreEqual("cba", result);
//verify that the method was called on the mock
channelMock.Verify(c => c.GetArticleBody(1010000008), Times.Once());
}
Besides that I think there is no problem with your approach. Maybe the view model violates the single responsibility principle and does more than it should, but that's hard to tell on the basis of your code example.
EDIT: Here's a full example of how you could test something like this:
public interface IMyService
{
int GetData();
}
public class MyViewModel
{
private readonly IMyService myService;
public MyViewModel(IMyService myService)
{
if (myService == null)
{
throw new ArgumentNullException("myService");
}
this.myService = myService;
}
public string ShowSomething()
{
return "Just a test " + this.myService.GetData();
}
}
class TestClass
{
[TestMethod]
public void TestMethod()
{
var serviceMock = new Mock<IMyService>();
var objectUnderTest = new MyViewModel(serviceMock.Object);
serviceMock.Setup(x => x.GetData()).Returns(42);
var result = objectUnderTest.ShowSomething();
Assert.AreEqual("Just a test 42", result);
serviceMock.Verify(c => c.GetData(), Times.Once());
}
}
Without access to your viewmodel, there's only so much help that we can provide you.
However, this code:
Mock<IIsesServiceChannel> channelMock = new Mock<IIsesServiceChannel>(MockBehavior.Strict);
...
ArticleDataGridViewModel articleDataGridViewModel = new ArticleDataGridViewModel(channelMock.Object);
...
string result = articleDataGridViewModel.IsesService.GetArticleBody(1010000008);
Does not set up your IsesService. If it is not set up in your constructor, that means the IsesService is a null reference. You can't call a method on a null object.
Consider mocking out at a higher level of abstraction then the tight coupling you have with the tool your using.
Perhaps your view-model should rely on services and not a detail of the tool that your using (i.e. IIsesServiceChannel).
Here's an example:
Construct testable business layer logic
I'm new to AutoFixture and am trying to create a friendly extension on my test context for the less TDD-inclined devs in the team. Here is the code:
public class HomeController : Controller
{
private readonly ISomeService _someService;
public HomeController(ISomeService someService)
{
_someService = someService;
}
public ActionResult Index()
{
_someService.SomeMethod();
return View("Index");
}
}
public class ControllerContext<T> where T : Controller
{
protected static T ControllerUnderTest;
private static IFixture _fixture;
public ControllerContext()
{
_fixture = new Fixture().Customize(new AutoMoqCustomization());
_fixture.Customize<ControllerContext>(c => c.Without(x => x.DisplayMode));
ControllerUnderTest = _fixture.Create<T>();
}
protected static Mock<TDouble> For<TDouble>() where TDouble : class
{
//var mock = _fixture.Create<TDouble>();
var mock = _fixture.Create<Mock<TDouble>>();
return mock;
}
}
So the extension is the For method - When I inspect ControllerUnderTest which has an injected 'ISomeService' it has an instance injected just fine, and it definitely calls the method I am asserting against. When I inspect the mock created in the 'For' method it appears to be the same version as the one injected to the controller, but it won't Verify!
public class EXAMPLE_When_going_to_home_page : ControllerContext<HomeController>
{
Because of = () =>
{
ControllerUnderTest.Index();
};
It should_do_something = () =>
{
//This throws a 'Invocation was not performed'
For<ISomeService>().Verify(x => x.SomeMethod());
};
Establish context = () =>
{
};
}
I am struggling to find any examples of someone doing something similar, I know I am definitely doing something stupid here but in my head this test should pass?
Create creates a new anonymous instance every time, unless you froze (via .Freeze<T>() or AutoFixture.Xunit's [Frozen]) an instance. That means that the value that is injected into HomeController is different from the one returned by For.
There are several possible solutions, all of which ultimately will involve Freezing the value or Injecting the one to use.
One example would look like this:
public class ControllerContext<T> where T : Controller
{
private static Lazy<T> _controllerFactory;
private static IFixture _fixture;
public ControllerContext()
{
_fixture = new Fixture().Customize(new AutoMoqCustomization());
_fixture.Customize<ControllerContext>(c => c.Without(x => x.DisplayMode));
_controllerFactory = new Lazy<T>(() => _fixture.Create<T>());
}
protected static Mock<TDouble> For<TDouble>() where TDouble : class
{
var mock = _fixture.Freeze<Mock<TDouble>>();
return mock;
}
protected static T ControllerUnderTest
{
get { return _controllerFactory.Value; }
}
}
public class EXAMPLE_When_going_to_home_page : ControllerContext<HomeController>
{
static Mock<ISomeService> SomeService;
Because of = () =>
{
SomeService = For<ISomeService>();
ControllerUnderTest.Index();
};
It should_do_something = () =>
{
//This throws a 'Invocation was not performed'
SomeService.Verify(x => x.SomeMethod());
};
Establish context = () =>
{
};
}
The important point of this changed version is that first Freeze is called on the service mock and only after that the anonymous instance of the controller is created. Because of the way the For method is now used, you should probably rename it to GetService.
You'll ultimately end up in a world of pain if you go down the road of having static state as a way of managing the interaction between the services and the SUT. One reason is for example that unit tests should be parallelizable (e.g. xUnit.net v2 but ultimately all test frameworks as it just makes sense)
You can add Customizations to AutoFixture to allow natural creation of MVC Controllers as needed and then it's just a matter of feeding in or Freezing customized dependencies as necessary.
I'd strongly suggest taking the time to change your structure of your tests to have AutoFixture creating the Controller declaratively - have a look at what's possible with AutoFixture.Xunit and use that to inform how you structure the test helpers you're using in your Specs.
(Some background - I've been around the houses with all this Spec stuff using SubSpec and ultimately ended up much happier with AutoFixture.Xunit - it's just simpler and more composable.
I have a named registration like this:
Unity.Container.RegisterType<IScheduler, DailyScheduler>("Daily");
This is how I resolve interfaces at runtime:
var Scheduler = Unity.Container.Resolve<IScheduler>("Daily");
I override this registration in my Test class like this:
var schedulerMock = new Mock<IScheduler>();
schedulerMock.SetupSet(s => s.IntervalString = It.IsAny<string>());
Unity.Container.RegisterInstance("Daily", schedulerMock.Object);
The problem is that the code is always resolving IScheduler to a DailyScheduler type not the mock object resulting in the VerifyAll method to fail. Am I missing something?
Are you using Unity 2.0? It works for me, at least using an instance of the container. I just tried it in LINQPad:
void Main()
{
IUnityContainer container = new UnityContainer();
container.RegisterType<IScheduler, DailyScheduler>("Daily");
var schedulerMock = new Mock<IScheduler>();
schedulerMock.Setup(x => x.Name).Returns("Mock!");
container.RegisterInstance("Daily", schedulerMock.Object);
IScheduler s = container.Resolve<IScheduler>("Daily");
Console.WriteLine(s.Name); // Prints "Mock!"
}
public interface IScheduler
{
string Name { get; }
}
public class DailyScheduler: IScheduler
{
public string Name { get { return "Daily!"; } }
}
Assuming Unity.Container is a Singleton, is it possible that code is changing the registration after the test setup calls RegisterInstance?
I wish to stub all dependencies out in my Rhino.Mocks unit tests, but I end up repeating myself. As the number of dependencies keeps increasing, I need to revisit my existing unit tests and need to add the dependencies. It's unsatisfying and also a signal that I should be doing it in another way.
If I just move initialization to a separate method, I pass into it all the mocks and I have achieved nothing.
Is there a way to initialize and then pass the Using(mocks.Record) into a method as a lambda expression? Or how do you do it?!
Thanks in advance for any comments,
Anders, Denmark
[Test, Category("UnitTest")]
public void TestThatApplicationCanExitByDefault()
{
var mocks = new MockRepository();
var workspaceViewModelProvider = mocks.StrictMock<IWorkspaceViewModelProvider>();
var workspaceRepository = mocks.StrictMock<IWorkspaceService>();
var userResponseProvider = mocks.StrictMock<IUserResponseProvider>();
var versionProvider = mocks.StrictMock<IVersionProvider>();
var eventAggregator = mocks.StrictMock<IEventAggregator>();
var allowedLegacyImportProvider = mocks.StrictMock<IAllowedLegacyImportProvider>();
var stateManager = mocks.StrictMock<IStateManager>();
var currentWorkspaceChangedEvent = mocks.StrictMock<CurrentWorkspaceChangedEvent>();
using (mocks.Record())
{
// constructor fires:
eventAggregator
.Stub(x => x.GetEvent<CurrentWorkspaceChangedEvent>())
.Return(currentWorkspaceChangedEvent);
currentWorkspaceChangedEvent
.Stub(x => x.Subscribe(null))
.IgnoreArguments();
}
var target = new MainWindowViewModel(
workspaceViewModelProvider,
workspaceRepository,
userResponseProvider,
versionProvider, eventAggregator, allowedLegacyImportProvider, stateManager);
var canAppExit = target.CanAppExit();
Assert.IsTrue(canAppExit);
mocks.VerifyAll();
}
[Test, Category("UnitTest")]
public void TestThatInsertProjectWorks()
{
var mocks = new MockRepository();
var workspaceViewModelProvider = mocks.StrictMock<IWorkspaceViewModelProvider>();
var workspaceRepository = mocks.StrictMock<IWorkspaceService>();
var userResponseProvider = mocks.StrictMock<IUserResponseProvider>();
var versionProvider = mocks.StrictMock<IVersionProvider>();
var eventAggregator = mocks.StrictMock<IEventAggregator>();
var allowedLegacyImportProvider = mocks.StrictMock<IAllowedLegacyImportProvider>();
var stateManager = mocks.StrictMock<IStateManager>();
var currentWorkspaceChangedEvent = mocks.StrictMock<CurrentWorkspaceChangedEvent>();
var workspaceViewModel = mocks.StrictMock<IWorkspaceViewModel>();
using (mocks.Record())
{
// constructor fires:
eventAggregator
.Stub(x => x.GetEvent<CurrentWorkspaceChangedEvent>())
.Return(currentWorkspaceChangedEvent);
currentWorkspaceChangedEvent
.Stub(x => x.Subscribe(null))
.IgnoreArguments();
workspaceViewModelProvider
.Stub(x => x.GetViewModel())
.Return(workspaceViewModel);
workspaceViewModel
.Stub(x => x.InsertProject());
}
var target = new MainWindowViewModel(
workspaceViewModelProvider,
workspaceRepository,
userResponseProvider,
versionProvider, eventAggregator, allowedLegacyImportProvider, stateManager);
target.InsertProject();
mocks.VerifyAll();
}
I tend to have a helper method which is responsible for building my mocks, and this method takes a lambda. The lambda can then communicate the mocks to a test. I have overloads of the test helper method to form an API and thus restrict what mocks are available to the test. In this way mock building can be centralized and so minimize dependency tramping across your tests.
It's more obvious with an example. This uses Moq, but the technique is general.
private static void RunTest(Action<IThing1> test)
{
RunTest(test: (thing1, thing2, thing3) => test(thing1));
}
private static void RunTest(Action<IThing1, IThing2> test)
{
RunTest(test: (thing1, thing2, thing3) => test(thing1, thing2));
}
private static void RunTest(Action<IThing1, IThing2, IThing3> test)
{
IThing1 thing1 = new Mock<IThing1>().Object;
IThing2 thing2 = new Mock<IThing2>().Object;
IThing3 thing3 = new Mock<IThing3>().Object;
test(thing1, thing2, thing3);
}
[Test]
public void do_some_stuff_to_a_thing()
{
RunTest(test: thing1 => {
//Do some testing....
});
}
[Test]
public void do_some_stuff_to_things()
{
RunTest(test: (thing1, thing2) => {
//Do some testing....
});
}
Try using a base class with protected mocked objects and use [SetUp]/[TestFixtureSetUp] (with NUnit for example).
It is wise to put only common objects with initialization to base class - use [SetUp]/[TestFixtureSetUp] in the same class where there are multiple unit tests and you need to mock/initialize something specific only to this tests. Putting everything in your base bloats your unit tests as well (at least they execute longer).