I have MockupController class with Just Mock and using the template found here
http://blog.johnnyreilly.com/2013/02/unit-testing-mvc-controllers-mocking.html#comment-2562756456
Tthe MockController class file that also includes the ability to mock a custom identity class that inherits from IIdentity.
While this class is useful it's still not mocking all the necessary aspects including routing.
Currently an error is being thrown with these two lines of the application code
UrlHelper u = new UrlHelper(ControllerContext.RequestContext);
string url = u.Action("Results", new { id = v.VerificationID });
Any ideas?
Here is the MockupController class
using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Telerik.JustMock;
using Telerik.JustMock.AutoMock;
using System.Web;
using QmostWeb.Controllers;
using System.Web.Mvc;
using System.Web.Routing;
using System.Security.Principal;
using QmostWeb;
using QmostWeb.Models;
using QmostBase;
using System.Collections.Specialized;
namespace QmostWebTest
{
public static class ControllerMockup
{
#region Mock HttpContext factories
public static HttpContextBase MockHttpContext()
{
var context = Mock.Create<HttpContextBase>();
var request = Mock.Create<HttpRequestBase>();
var response = Mock.Create<HttpResponseBase>();
var session = Mock.Create<HttpSessionStateBase>();
var server = Mock.Create<HttpServerUtilityBase>();
Mock.Arrange(() => request.AppRelativeCurrentExecutionFilePath).Returns("/");
Mock.Arrange(() => request.ApplicationPath).Returns("/");
Mock.Arrange(() => request.IsAuthenticated).Returns(true);
Mock.Arrange(() => response.ApplyAppPathModifier(Arg.IsAny<string>())).Returns<string>(s => s);
Mock.ArrangeSet(() => response.StatusCode = (int) System.Net.HttpStatusCode.OK);
Mock.Arrange(() => context.Request).Returns(request);
Mock.Arrange(() => context.Response).Returns(response);
Mock.Arrange(() => context.Session).Returns(session);
Mock.Arrange(() => context.Server).Returns(server);
return context;
}
public static HttpContextBase MockHttpContext(string url)
{
var context = MockHttpContext();
context.Request.SetupRequestUrl(url);
return context;
}
#endregion
public static void SetMockControllerContext(this Controller controller,
HttpContextBase httpContext = null,
RouteData routeData = null,
RouteCollection routes = null)
{
routeData = routeData ?? new RouteData();
routes = routes ?? RouteTable.Routes;
httpContext = httpContext ?? MockHttpContext();
var requestContext = new RequestContext(httpContext, routeData);
var user = new QmostIdentitySerializeModel()
{
UserId = 20,
SecurityToken = new Guid("4223017F-E6F2-4829-A37F-51C42CF1A04C")
};
var qmostIdentity = new QmostIdentity("jonathan", user, new QmostWorkflowsSerializeModel());
var principal = Mock.Create<IPrincipal>();
Mock.Arrange(() => principal.Identity).Returns(qmostIdentity);
var context = new ControllerContext(requestContext, controller);
Mock.Arrange(() => context.HttpContext.User).Returns(principal);
controller.ControllerContext = context;
}
public static void SetupRequestUrl(this HttpRequestBase request, string url)
{
if (url == null)
throw new ArgumentNullException("url");
if (!url.StartsWith("~/"))
throw new ArgumentException("Sorry, we expect a virtual url starting with \"~/\".");
Mock.Arrange(() => request.QueryString).Returns(GetQueryStringParameters(url));
Mock.Arrange(() => request.AppRelativeCurrentExecutionFilePath).Returns(GetUrlFileName(url));
Mock.Arrange(() => request.PathInfo).Returns(string.Empty);
}
#region Private
static string GetUrlFileName(string url)
{
return (url.Contains("?"))
? url.Substring(0, url.IndexOf("?"))
: url;
}
static NameValueCollection GetQueryStringParameters(string url)
{
if (url.Contains("?"))
{
var parameters = new NameValueCollection();
var parts = url.Split("?".ToCharArray());
var keys = parts[1].Split("&".ToCharArray());
foreach (var key in keys)
{
var part = key.Split("=".ToCharArray());
parameters.Add(part[0], part[1]);
}
return parameters;
}
return null;
}
#endregion
}
}
I have a async method under test and this method calls a rest service asynchronously, I want to test that if the rest service call returns an error then this method under test throws it back, I am guessing because of the way the exception are wrapped in a Task it is not working for me.
If i debug I can see that service.restcall does throw the exception with "Test" but the test method never receives the error.
public async Task CreateDatastore()
{
await service.restcall()
}
-------------- Test code -----------------
[TestMethod]
[ExpectedException(typeof(Exception), "Test")]
public void Should_Throw_Back_The_RestException()
{
//Arrange
var service = Mock.Create<IRestApiServices>();
var viewModel = new CreateViewModel(service);
var privViewModel = new PrivateAccessor(viewModel);
var ex = new Exception("Test");
Mock.Arrange(() => service.restcall().IgnoreArguments().throws(ex).MustBeCalled();
//Act
privViewModel.CallMethod("Methodundertest", null);
//Assert
Mock.Assert(service);
}
I have 2 classes Parent and a Child class, child class inherits from parent.
Class under test has an async method that returns Task<parent>.
I am arranging the Test method in my unit test, Mock.Arrange(() => viewmodel.Test()).Returns(Task.FromResult(new child()));
I am getting this error, Why is it having a problem in casting a child to its parenttype
ErrorCS1503Argument 1: cannot convert from 'System.Threading.Tasks.Task<ViewModels.child>' to 'System.Threading.Tasks.Task<ViewModels.parent>'ViewModels.Tests
public class viewmodel{
public async Task<parent> Test()
{
await Task.Delay(100);
return null;
}
}
public class parent
{
}
public class child : parent
{
}
Hi,
I am new to justmock, bear with me if I have some basic questions wrong.
We have few unit tests that run fine when I run them locally, but when I checkin them in TFS then it fails the gated-checkin.
I know this can be caused from a range of reasons, but I have reason to believe that one of the mocked method is not getting mocked in the server.
Here is how the code looks,
public void My_Failing_Test()
{
Test_Class_Accessor target = new Test_Class_Accessor();
target.DataLayer = GetMockLayer();
// Set up data
Test_Class mockTest = new Test_Class();
Mock.NonPublic.Arrange<
bool
>(mockPharm, "MockedPrivateMethod", ArgExpr.IsAny<
String
>(), ArgExpr.IsAny<
String
>(), ArgExpr.IsAny<
DateTime
>()).IgnoreArguments().IgnoreInstance().Returns(false);
target.UnderTestPrivateMethod();
//Asserts
}
UnderTestPrivateMethod has a call to MockedPrivateMethod
private static DataLayer GetMockLayer(......)
{
Features mockFeatures = Mock.Create<
Features
>(Constructor.NotMocked, Behavior.CallOriginal);
mockFeatures.someThing = new SomeThing{.....};
DataLayer mockLayer = Mock.Create<
DataLayer
>(Constructor.NotMocked, Behavior.CallOriginal);
mockLayer.TwoTier_Initialize();
Mock.Arrange(() => mockLayer.Features).Returns(mockFeatures);
return mockLayer;
}
I suspect for some reason both the mockFeatures.someThing and MockedPrivateMethod are not getting mocked.
Is there something wrong with what I am doing?
If someone has faces similar problem before, please let me know.
Appreciate the time, thanks
I'm wondering whether I am simply trying to achieve the impossible, but.....
I have successfully mocked up some legacy code and able to run my tests. I have then built a simple WPF app to utilise the same mocking approach and publish the results (without using test fixtures)
However, when I try to run the app outside of visual studio, I get the following exception:
Telerik.JustMock.Core.ElevatedMockingException
Message=Cannot mock 'System.String get_blah()'. The profiler must be enabled to mock, arrange or execute the specified target.
Source=Telerik.JustMock
I have checked the event viewer and the profiler is enabled.
Is this issue simply that this will never run outside of Visual Studio/any other test runner?
Ideally, we would like to be able to create a suite of automated regression testing apps for non-devs to use.
Kind Regards
ben
Hi all,
I have the following generic method in my class:
1.
private T ValidateApiResponse<
T
>(Document response) where T : ResponseBase
2.
{
3.
}
My test method looks like this:
01.
[TestMethod]
02.
public void CardCaptureRequest_CallsCreateRequest()
03.
{
04.
//Arrange
05.
var methodCalled = false;
06.
var facadeSettings = MockFacadeSettings("http://localhost", "logfile", 1, 2, "proxy");
07.
var authSettings = MockAuthenticationSettings("clientName", "password");
08.
var facade = Mock.Create<
DatacashFacade
>(Behavior.CallOriginal, new object[] { facadeSettings, authSettings });
09.
var document = Mock.Create<
Document
>();
10.
var ccResponse = new CardCaptureResponse
11.
{
12.
Status = 1,
13.
DatacashReference = "refNo",
14.
Information = "Info",
15.
MerchantReference = "merchRef",
16.
RedirectUrl = "http://localhost/",
17.
Success = true
18.
};
19.
20.
Mock.NonPublic.Arrange<
Document
>(facade, "CreateRequest")
21.
.DoInstead(() =>
22.
{
23.
methodCalled = true;
24.
}).Returns(document);
25.
Mock.NonPublic.Arrange<
Document
>(facade, "SendRequest")
26.
.IgnoreInstance().Returns(document);
27.
28.
Mock.NonPublic.Arrange<
CardCaptureResponse
>(facade, "ValidateApiResponse", document)
29.
.Returns(ccResponse);
30.
31.
//Act
32.
facade.CardCaptureRequest(1, "", 2, "", "", "");
33.
34.
//Assert
35.
Assert.IsTrue(methodCalled);
36.
}
Line 28 is attempting to Mock the private method call.
However, the test fails with the following: Method 'ValidateApiResponse' with the given signature was not found on type .......
Any ideas??
from audit
in
_context.Audits
where audit.DTS < EntityFunctions.TruncateTime(mydate)
select audit
var fakeEntities = Mock.Create<SomeDBEntities>();
var audits = GetAudits();
Mock.Arrange(() => fakeEntities.Audits).ReturnsCollection(audits);
var target =
new
ReportRepository(fakeEntities);
var result = target.test(DateTime.Now);
Assert.AreEqual(2, result.Count());
Here is an example of what I'd like to mock up?
namespace
ExternalAssembly
{
internal
enum
HintArg { Flag1,Flag2,Flag3}
public
class
ExternalClass
{
private
int
MethodToMock(
string
name, HintArg hint,
out
string
result)
{
result =
"I want to override this"
;
return
0;
}
}
}
In this example what I'd like to have is a setup that will call the original MethodToMock on everything except when I have a specific name match?
I have something along the lines of:
string
mockName=
"mockName"
;
string
mockResult =
"new result"
;
Mock.NonPublic.Arrange(
typeof
(ExternalClass),
"MethodToMock"
,mockName,ArgExpr.IsAny<HintArg>(),ArgExpr.Out<
string
>(newResult).Returns(0);
I'm just not sure how to specify the arg expression when the type is an internal that my invoking assembly is not friends with?
Downloaded the trial of JustMock since so many of the problems I have been facing are supposed to be addressable with it. I'm attempting to Mock an EF 6.1.3 DBContext. I have can build a test that runs directly against the DB and it works fine, but when I run against the Mocked Context I get an exception.
To be clear I am using JustMock version 2015.3.929.5 also per the documentation I downloaded JustMock.EntityFramework from Nuget version 1.0.1. The Nuget installed incorrectly into the project and tried to explicitly target JustMock 2014.1.1424.1, but I corrected the config file back to the currently referenced version as mentioned above.
Here is my code.
public
class
Account
{
public
int
Id {
get
;
set
; }
[Required]
public
string
ExternalId {
get
;
set
; }
public
string
AccountTimeZone {
get
;
set
; }
public
string
FipsCode {
get
;
set
; }
public
bool
DVREnabled {
get
;
set
; }
public
bool
Enabled {
get
;
set
; }
public
double
CreditLimit {
get
;
set
; }
public
int
SdStreams {
get
;
set
; }
public
int
HdStreams {
get
;
set
; }
[Column(TypeName=
"DateTime2"
)]
public
DateTime CreatedTimeUTC {
get
;
set
; }
[Column(TypeName =
"DateTime2"
)]
public
DateTime LastUpdateTimeUTC {
get
;
set
; }
public
string
CreatedBy {
get
;
set
; }
public
string
UpdatedBy {
get
;
set
; }
public
AccountStatus AccountStatus {
get
;
set
; }
public
List<Device> Devices {
get
;
set
; }
public
List<SubscriberGroup> SubscriberGroups {
get
;
set
; }
public
List<AccountValue> AccountValues {
get
;
set
; }
public
SubscriberInfo SubscriberInfo {
get
;
set
; }
public
Device RecordingDevice {
get
;
set
; }
[Required]
public
Tenant Tenant {
get
;
set
; }
public
List<Phone> Phones {
get
;
set
; }
public
List<AccountHistory> AccountHistory {
get
;
set
; }
}
public
class
Tenant
{
public
int
Id {
get
;
set
; }
public
string
TenantName {
get
;
set
; }
public
string
TenantDescription {
get
;
set
; }
public
string
MediaroomVersion {
get
;
set
; }
public
TenantConfiguration TenantConfiguration {
get
;
set
; }
public
List<Account> Accounts {
get
;
set
; }
public
List<Device> Devices {
get
;
set
; }
public
List<ChangeEvent> ChangeEvents {
get
;
set
; }
}
public
class
EmptyAccount
{
public
void
CreateEmptyAccountInConductor(Account newAccount,
int
tenantId,
string
requestedBy, UnitOfWork uow)
{
var tr =
new
TenantRepository(uow);
var tenant = tr.Find(tenantId);
tenant.Accounts.Add(
new
Account(){ExternalId = newAccount.ExternalId, CreatedBy = requestedBy});
tr.InsertOrUpdate(tenant);
uow.Save();
}
}
public
class
TenantRepository : ITenantRepository
{
private
readonly
ConductorContext _context;
public
TenantRepository(UnitOfWork uow)
{
_context = uow.Context;
}
public
Tenant Find(
int
id)
{
return
_context.Tenants.Find(id);
}
public
void
InsertOrUpdate(Tenant entity)
{
if
(entity.Id ==
default
(
int
))
{
_context.Entry(entity).State = EntityState.Added;
}
else
{
_context.Entry(entity).State = EntityState.Modified;
}
}
}
public
class
ConductorContext : DbContext
{
public
ConductorContext()
{
base
.Configuration.ProxyCreationEnabled =
false
;
}
public
DbSet<Account> Accounts {
get
;
set
; }
public
DbSet<AccountHistory> AccountHistories {
get
;
set
; }
public
DbSet<AccountTemplate> AccountTemplates {
get
;
set
; }
public
DbSet<AccountValue> AccountValues {
get
;
set
; }
public
DbSet<ChangeEvent> ChangeEvents {
get
;
set
; }
public
DbSet<Device> Devices {
get
;
set
; }
public
DbSet<DeviceValue> DeviceValues {
get
;
set
; }
public
DbSet<Phone> Phones {
get
;
set
; }
public
DbSet<SubscriberGroup> SubscriberGroups {
get
;
set
; }
public
DbSet<SubscriberInfo> SubscribersInfo {
get
;
set
; }
public
DbSet<Tenant> Tenants {
get
;
set
; }
public
DbSet<TenantConfiguration> TenantConfigurations {
get
;
set
; }
}
public
class
UnitOfWork : IUnitOfWork<ConductorContext>
{
private
readonly
ConductorContext _context;
public
UnitOfWork()
{
_context =
new
ConductorContext();
}
public
UnitOfWork(ConductorContext context)
{
_context = context;
}
public
int
Save()
{
return
_context.SaveChanges();
}
public
void
Dispose()
{
_context.Dispose();
}
public
ConductorContext Context
{
get
{
return
_context; }
}
}
Direct to DB test that works.
[Test]
public
void
CreateEmptyAccountInConductor4()
{
// Arrange
Database.SetInitializer(
new
DropCreateDatabaseAlways<ConductorContext>());
var ctx =
new
ConductorContext();
var fixture =
new
Fixture();
var account = fixture.Build<Account>()
.Without(p => p.Id)
.Without(p => p.Tenant)
.Without(p => p.AccountHistory)
.Without(p => p.AccountValues)
.Without(p => p.Devices)
.Without(p => p.Phones)
.Without(p => p.SubscriberGroups)
.Without(p => p.SubscriberInfo)
.Without(p => p.RecordingDevice)
.Without(p => p.CreatedTimeUTC)
.Without(p => p.LastUpdateTimeUTC)
.Create();
var tenant = fixture.Build<Tenant>()
.With(p => p.Id, 1)
.With(p => p.MediaroomVersion,
"V2"
)
.Without(p => p.Accounts)
.Without(p => p.Devices)
.Without(p => p.ChangeEvents)
.With(p => p.TenantConfiguration,
new
TenantConfiguration())
.Create();
ctx.Tenants.Add(tenant);
ctx.SaveChanges();
// Act
var sut =
new
EmptyAccount();
sut.CreateEmptyAccountInConductor(account, 1, fixture.Create<
string
>(),
new
UnitOfWork(ctx));
ctx.Dispose();
// Assert
ctx =
new
ConductorContext();
// Force entity to load into context.
var tenantAfter = ctx.Tenants.Find(1);
var accountAfter = ctx.Accounts.Find(1);
Assert.AreEqual(account.ExternalId, ctx.Tenants.Find(1).Accounts.Single(p => p.ExternalId == account.ExternalId).ExternalId);
}
Mocked Context that fails with a NullReferanceException in the InsertOrUpdate method of TenantRepository.
[Test]
public
void
CreateEmptyAccountInConductor3()
{
// Arrange
var ctx = Mock.Create<ConductorContext>().PrepareMock();
var fixture =
new
Fixture();
var account = fixture.Build<Account>()
.Without(p => p.Id)
.Without(p => p.Tenant)
.Without(p => p.AccountHistory)
.Without(p => p.AccountValues)
.Without(p => p.Devices)
.Without(p => p.Phones)
.Without(p => p.SubscriberGroups)
.Without(p => p.SubscriberInfo)
.Without(p => p.RecordingDevice)
.Without(p => p.CreatedTimeUTC)
.Without(p => p.LastUpdateTimeUTC)
.Create();
var tenant = fixture.Build<Tenant>()
.With(p => p.Id, 1)
.With(p => p.MediaroomVersion,
"V2"
)
.With(p => p.Accounts,
new
List<Account>())
.Without(p => p.Devices)
.Without(p => p.ChangeEvents)
.With(p => p.TenantConfiguration,
new
TenantConfiguration())
.Create();
var tenantList =
new
List<Tenant>()
{
tenant
};
ctx.Tenants.Bind(tenantList);
// Act
var sut =
new
EmptyAccount();
sut.CreateEmptyAccountInConductor(account, 1, fixture.Create<
string
>(),
new
UnitOfWork(ctx));
// Assert
Mock.Assert(() => ctx.SaveChanges(), Occurs.Once());
}
My assertion test for the Mocked Context is never even reached in the failing test. At this point I assume I'm doing something wrong. Any idea how I can get this to work because I don't want to be creating dropping my database over and over to run my test. This is just one of many I need to write like this.