Moq Event Aggregator Is it possible - moq

Wondering if its possible to Moq the Prism EventAggregator
Let's take the EventAggregator Quickstart they have
[TestMethod]
public void PresenterPublishesFundAddedOnViewAddClick()
{
var view = new MockAddFundView();
var EventAggregator = new MockEventAggregator();
var mockFundAddedEvent = new MockFundAddedEvent();
EventAggregator.AddMapping<FundAddedEvent>(mockFundAddedEvent);
var presenter = new AddFundPresenter(EventAggregator);
presenter.View = view;
view.Customer = "99";
view.Fund = "TestFund";
view.PublishAddClick();
Assert.IsTrue(mockFundAddedEvent.PublishCalled);
Assert.AreEqual("99", mockFundAddedEvent.PublishArgumentPayload.CustomerId);
}
I have tried to convert the above using moq but I get problems
they have MockEventAggregator.How can I do that using Moq?
public class MockEventAggregator : IEventAggregator
{
Dictionary<Type, object> events = new Dictionary<Type, object>();
public TEventType GetEvent<TEventType>() where TEventType : EventBase
{
return (TEventType)events[typeof(TEventType)];
}
public void AddMapping<TEventType>(TEventType mockEvent)
{
events.Add(typeof(TEventType), mockEvent);
}
}
Has anybody used MOQ and the EventAggregator are there any examples out there?
Thanks a lot
EDIT
Following GrameF Answer I have added my code that still does not work.Can you help
[TestMethod]
public void PresenterPublishesFundAddedOnViewAddClick2()
{
//Arrange
var view = new Mock<IAddFundView>();
var fakeEventAggregator = new Mock<IEventAggregator>();
var fakeMyEvent = new Mock<FundAddedEvent>();
fakeEventAggregator.Setup(x => x.GetEvent<FundAddedEvent>()).Returns(fakeMyEvent.Object);
var presenter = new AddFundPresenter(fakeEventAggregator.Object) {View = view.Object};
fakeMyEvent.Verify(x => x.Publish(It.IsAny<FundOrder>())); **//CRASHES** HERE
//view.PublishAddClick();
//view.Customer = "99";
//view.Fund = "TestFund";
//view.PublishAddClick();
////Assert
//Assert.IsTrue(mockFundAddedEvent.PublishCalled);
//Assert.AreEqual("99", mockFundAddedEvent.PublishArgumentPayload.CustomerId);
//Assert.AreEqual("TestFund", mockFundAddedEvent.PublishArgumentPayload.TickerSymbol);
}

Yes, it's possible, you just need to set it up to return a mock event on which you can verify that Publish or Subscribe was called:
var fakeEventAggregator = new Mock<IEventAggregator>();
var fakeMyEvent = new Mock<MyEvent>();
fakeEventAggregator.
Setup(x => x.GetEvent<MyEvent>()).
Returns(fakeMyEvent.Object);
var test = new Foo(fakeEventAggregator.Object);
test.PublishAnEvent();
fakeMyEvent.Verify(x => x.Publish(It.IsAny<MyEventArgs>()));

Related

How to unit test the controller?

I have the controller in ASP.NET Mvc 6.
public class VendorManagementController : Controller
{
private readonly IVendorRespository _vendorRespository;
public VendorManagementController(IVendorRespository vendorRespository)
{
_vendorRespository = vendorRespository;
}
[Microsoft.AspNet.Mvc.HttpGet]
public dynamic GetVendorById(int pkey)
{
Vendor vendor = _vendorRespository.GetVendor(pkey);
return vendor;
}
// GET
// USing JqGrid
[Microsoft.AspNet.Mvc.HttpGet]
public dynamic GetVendors(string sidx, string sortOrder, int page, int rows, int pkey)
{
var vendors = _vendorRespository.GetAllVendors().AsQueryable();
var pageIndex = Convert.ToInt32(page) - 1;
var pageSize = rows;
var totalRecords = vendors.Count();
var totalPages = (int)Math.Ceiling((float)totalRecords / (float)pageSize);
return something
}
// POST
[System.Web.Http.HttpPost]
public string PostVendor(Vendor item)
{
_vendorRespository.AddVendor(item);
}
The link provides an example to test the controller, but it uses HttpRequestMessage. It doesn't fit my case.
So if I want to test the return Vendors, how?
Say I have the method:
[Fact]
public void GetAllVendors_ShouldReturnAllVendors()
{
var testVendors = GetTestVendors();
var vendorRespository = new VendorRespository();
var controller = new VendorManagementController(vendorRespository);
}
The thing is
var vendors = _vendorRespository.GetAllVendors().AsQueryable();
from the databse, how to mock up it with my fake vendors?
EDIT:
The method returns dynamic type, I can't get the Count of the list.
Install a mocking framework such as Moq from nuget - https://www.nuget.org/packages/Moq/.
using Moq;
[Fact]
public void GetAllVendors_ShouldReturnAllVendors()
{
var testVendors = GetTestVendors();
var vendorRespository = new Mock<IVendorRepository>();
vendorRepository.Setup(m => m.GetAllVendors()).Returns(new List<Vendor> { new Vendor() }); // Guessing a bit on return types
var controller = new VendorManagementController(vendorRespository.Object);
var result = controller.GetVendors( ... )
// Assert you get 1 Vendor back, not sure what you're planning to return by "something". :-)
}
Other frameworks are available, NSubsititute, FakeItEasy

How to test a class with delegate in constructor using Moq

Can someone explain to me how to create an instance of this component in a Moq TestMethod? Here is the definition of the class. I need to test the ProcessAutomaticFillRequest method.
public class AutomaticDispenserComponent : IAutomaticDispenserComponent
{
private readonly Lazy<IMessageQueueComponent> _messageQueueComponent;
protected IMessageQueueComponent MessageQueueComponent { get { return _messageQueueComponent.Value; } }
public AutomaticDispenserComponent(Func<IMessageQueueComponent> messageQueueComponentFactory)
{
_messageQueueComponent = new Lazy<IMessageQueueComponent>(messageQueueComponentFactory);
}
public void ProcessAutomaticFillRequest(FillRequestParamDataContract fillRequestParam)
{
if (fillRequestParam.PrescriptionServiceUniqueId == Guid.Empty)
throw new InvalidOperationException("No prescription service was specified for processing fill request.");
if (fillRequestParam.Dispenser == null)
throw new InvalidOperationException("No dispenser was specified for processing fill request.");
var userContext = GlobalContext.CurrentUserContext;
var channel = string.Format(Channel.FillRequest, userContext.TenantId,
userContext.PharmacyUid, fillRequestParam.Dispenser.DeviceAgentUniqueId);
NotificationServer.Publish(channel, fillRequestParam);
}
Here is how I started my test, but I don't know how to create an instance of the component:
[TestMethod]
[ExpectedException(typeof (InvalidOperationException))]
public void FillRequestFailsWhenPrescriptionServiceUniqueIdIsEmpty()
{
// How do I create an instance of automatiqueDispenserComponent here
// since there is Func as constructor parameter?
var fillRequestParam = new FillRequestParamDataContract
{
PrescriptionServiceUniqueId = Guid.Empty
};
_automaticDispensercomponent.ProcessAutomaticFillRequest(fillRequestParam);
// ...
}
Updated the answer based on the comments below. You need to mock the Func parameter for the test.
[TestMethod]
[ExpectedException(typeof(InvalidOperationException))]
public void FillRequestFailsWhenPrescriptionServiceUniqueIdIsEmpty()
{
var mockMsgQueueComponent = new Mock<Func<IMessageQueueComponent>>();
var _automaticDispensercomponent = new AutomaticDispenserComponent
(mockMsgQueueComponent.Object);
var fillRequestParam = new FillRequestParamDataContract
{
PrescriptionServiceUniqueId = Guid.Empty
};
_automaticDispensercomponent.ProcessAutomaticFillRequest(fillRequestParam);
}

Faking Http Context with Moq and Mvc

I’m trying to fake http context to test a Controller. My environment is MVC 3 and Moq 4.
So far I have tried a few options including:
a.
var searchController = new MySearchController(_mockResolver.Object.Resolve<IConfiguration>());
var mockContext = new Mock<ControllerContext>();
searchController.ControllerContext = mockContext.Object;
var result = searchController.Render();
b.
var searchController = new MopSearchController(_mockResolver.Object.Resolve<IConfiguration>());
searchController.MockControllerContext();
var result = searchController.Render();
public static class MockHttpHelper
{
public static Mock<HttpContextBase> MockControllerContext(
this Controller controller, string path = null)
{
var mockHttpCtx = MockHttpHelper.MockHttpContext(path);
var requestCtx = new RequestContext(mockHttpCtx.Object, new RouteData());
var controllerCtx = new ControllerContext(requestCtx, controller);
controller.ControllerContext = controllerCtx;
return mockHttpCtx;
}
public static Mock<HttpContextBase> MockHttpContext(string path)
{
var mockHttpCtx = new Mock<HttpContextBase>();
var mockReq = new Mock<HttpRequestBase>();
mockReq.SetupGet(x => x.RequestType).Returns("GET");
mockReq.SetupGet(req => req.Form).Returns(new NameValueCollection());
mockReq.SetupGet(req => req.QueryString).Returns(new NameValueCollection());
mockHttpCtx.SetupGet(x => x.Request).Returns(mockReq.Object);
return mockHttpCtx;
}
}
Neither of these work, I get the exception below. Can anyone point me in the direction of a working example? I’ve seen quite a few questions on the net around the same topic, but given the date (posts from 2008-2010) and MVC version (i.e. 1 and 2) I feel like I’m missing something / or trying to mock more than I need to in MVC3.
System.NullReferenceException : Object reference not set to an instance of an object.
at System.Web.Mvc.ChildActionValueProviderFactory.GetValueProvider(ControllerContext controllerContext)
at System.Web.Mvc.ValueProviderFactoryCollection.<>c__DisplayClassc.<GetValueProvider>b__7(ValueProviderFactory factory)
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList(IEnumerable`1 source)
at System.Web.Mvc.ValueProviderFactoryCollection.GetValueProvider(ControllerContext controllerContext)
at System.Web.Mvc.Controller.TryUpdateModel(TModel model)
Thanks
Yes, all you were really missing, as you've noted, was setting the Controller's ValueProvider. Even though you're using this controller with a Get action but no Post action, the Controller still gets its ValueProvider instantiated upon creation, so you need to do the same thing in your test scenario. Here's the base class that I use when testing my controllers. I use NBehave's NUnit wrapper for unit testing, so ignore the SpecBase reference if you wish
public abstract class MvcSpecBase<T> : SpecBase<T> where T : Controller
{
protected T Controller { get; set; }
protected string RelativePath = string.Empty;
protected string AbsolutePath = string.Empty;
protected void InitialiseController(T controller, NameValueCollection collection, params string[] routePaths)
{
Controller = controller;
var routes = new RouteCollection();
RouteConfig.RegisterRoutes(routes);
var httpContext = ContextHelper.FakeHttpContext(RelativePath, AbsolutePath, routePaths);
var context = new ControllerContext(new RequestContext(httpContext, new RouteData()), Controller);
var urlHelper = new UrlHelper(new RequestContext(httpContext, new RouteData()), routes);
Controller.ControllerContext = context;
Controller.ValueProvider = new NameValueCollectionValueProvider(collection, CultureInfo.CurrentCulture);
Controller.Url = urlHelper;
}
}
Then, in your test, create your controller and then call this line:
InitialiseController(controller, new FormCollection());

How to moq the LinkQ extionsion method

How to moq the OfType to return
class A
{
public void iterate()
{
foreach (var aTool in Handler.Tools.OfType<IDrawTool>())
{
//some code
}
}
}
//tools implementes both interface ITool and IDrawTool
//wanted to get the tool which implements the IDrawTool from the
//Handler.Tools<ITool> list
Mock<List<ITool>> aToolMockList = new Mock<ITool>();
Mock<IDrawTool> adrawToolMock = new Mock<IDrawTool>();
aToolMockList.Setup(list => list.OfType<IDrawTool>()).Returns((IEnumerable<IDrawTool>) adrawToolMock .Object);
But the OfType throws the exception setup on a non-member method
Should I override this? What should I do?
List<ITool> aToolMockList = new List<ITool>();
Mock<IDrawTool> adrawToolMock = new Mock<IDrawTool>();
Mock<ITool> aToolMock = new Mock<ITool>;
//additional setups
aToolMockList.Add(adrawToolMock.object);
aToolMockList.Add(aToolMock.object);
//
A a = new A(aToolMockList);
A.iterate();
//
adrawToolMock.Toolwork.Verify(Times.Once);
aToolMock.Toolwork.Verify(Times.Never);
Something like that :)

How to unit test code that uses HostingEnvironment.MapPath

I have some code that uses HostingEnvironment.MapPath which I would like to unit test.
How can I setup HostingEnvironment so that it returns a path and not null in my unit test (mstest) project?
Why would you have a code that depends on HostingEnvironment.MapPath in an ASP.NET MVC application where you have access to objects like HttpServerUtilityBase which allow you to achieve this and which can be easily mocked and unit tested?
Let's take an example: a controller action which uses the abstract Server class that we want to unit test:
public class HomeController : Controller
{
public ActionResult Index()
{
var file = Server.MapPath("~/App_Data/foo.txt");
return View((object)file);
}
}
Now, there are many ways to unit test this controller action. Personally I like using the MVcContrib.TestHelper.
But let's see how we can do this using a mocking framework out-of-the-box. I use Rhino Mocks for this example:
[TestMethod]
public void Index_Action_Should_Calculate_And_Pass_The_Physical_Path_Of_Foo_As_View_Model()
{
// arrange
var sut = new HomeController();
var server = MockRepository.GeneratePartialMock<HttpServerUtilityBase>();
var context = MockRepository.GeneratePartialMock<HttpContextBase>();
context.Expect(x => x.Server).Return(server);
var expected = #"c:\work\App_Data\foo.txt";
server.Expect(x => x.MapPath("~/App_Data/foo.txt")).Return(expected);
var requestContext = new RequestContext(context, new RouteData());
sut.ControllerContext = new ControllerContext(requestContext, sut);
// act
var actual = sut.Index();
// assert
var viewResult = actual as ViewResult;
Assert.AreEqual(viewResult.Model, expected);
}
Well I was writing a test today for code that I don't control and they used
private static String GetApplicationPath()
{
return HostingEnvironment.ApplicationVirtualPath.TrimEnd('/');
}
so here is a C# reflection hack to set that value
var path = "/aaaa/bb";
HostingEnvironment hostingEnvironment;
if (HostingEnvironment.IsHosted.isFalse())
new HostingEnvironment();
hostingEnvironment = (HostingEnvironment)typeof(HostingEnvironment).fieldValue("_theHostingEnvironment");
var virtualPath = "System.Web".assembly()
.type("VirtualPath").ctor();
virtualPath.field("_virtualPath", path);
//return virtualPath.prop("VirtualPathString");
//return virtualPath.prop("VirtualPathStringNoTrailingSlash");
hostingEnvironment.field("_appVirtualPath", virtualPath);
//hostingEnvironment.field("_appVirtualPath") == virtualPath;
return HostingEnvironment.ApplicationVirtualPath == path;
//using System.Web.Hosting
It will depend on what mocking or isolation framework you are using. You might want to look into either a) creating a wrapper type around the static property that can be mocked, or b) using a framework which can mock static properties - e.g. Moles or Typemock Isolator
As i faced same issue i changed my code bit.
From
strhtmlTemplate = File.ReadAllText(System.Web.Hosting.HostingEnvironment.MapPath(Lgetfilepath.CVal));
To
strhtmlTemplate = File.ReadAllText(HttpContextFactory.Current.Server.MapPath(Lgetfilepath.CVal));
For Unit test
public HttpContextBase mockHttpContextBase()
{
var moqContext = new Mock<HttpContextBase>();
var moqRequest = new Mock<HttpRequestBase>();
var moqServer = new Mock<HttpServerUtilityBase>();
var moqPath = new Mock<ConfigurationBase>();
moqContext.Setup(x => x.Request).Returns(moqRequest.Object);
moqContext.Setup(x => x.Server.MapPath(#"~\Data\xxxxxxx")).Returns(Environment.CurrentDirectory+#"\xxxxxx");
setupApplication(moqContext);
return moqContext.Object;
}
Now we while Writing TestClass you need to refer above method to mock. Hope it will helpful for your TestCases.
MockDataUT mockData = new MockDataUT();
var mockRequestContext = new HttpRequestContext();
HttpContextFactory.SetCurrentContext(mockData.mockHttpContextBase());
Just use this code..
Make a new folder name Reference in root directory and added your file inside this folder.
Use this
public static XElement GetFile()
{
HttpContext.Current = new HttpContext(new HttpRequest("", "http://www.google.com", ""), new HttpResponse(new StringWriter()));
var doc = new XmlDocument();
var file = HttpContext.Current.Server.MapPath("\\") + "abc.xml";
doc.Load(file);
var e = XElement.Load(new XmlNodeReader(doc));
return e;
}

Resources