Got NullReferenceException when Unit testing Controller - asp.net-mvc-3

I am working on Unit testing the MVC3 site using NUnit, MvcContrib.TestHelper package but I am facing the exception "Object reference not set to an instance of an object" when my test method accesses the controller having TryUpdateModel. I dont know what to do to pass the test. please help me in this.
I am also giving a code for that :
Action from Controller which test method calls, is given below :
public JsonResult AddPatient()
{
bool returnStatus;
string returnErrorMessage;
List<string> returnMessage;
PatientBLL patientBLL = new PatientBLL();
Models.PatientViewModel patientViewModel = new Models.PatientViewModel();
TryUpdateModel(patientViewModel);
Patient patient = patientBLL.AddPatient(
patientViewModel,
out returnMessage,
out returnStatus,
out returnErrorMessage);
patientViewModel.UpdateViewModel(patient, typeof(Patient).GetProperties());
patientViewModel.ReturnMessage = returnMessage;
patientViewModel.ReturnStatus = returnStatus;
return Json(patientViewModel);
}
and the test method which calls the above action is given below :
[Test]
public void Test_AddPatient()
{
TestControllerBuilder builder = new TestControllerBuilder();
string uniquePatientKey = GenerateUniqueID();
builder.Form["MedicalID"] = uniquePatientKey;
builder.Form["SocialSecurityNumber"] = uniquePatientKey;
builder.Form["FirstName"] = "Khushi";
builder.Form["LastName"] = "Maahi";
builder.Form["AddressLine1"] = "ABCD";
builder.Form["AddressLine2"] = "Technologies";
builder.Form["City"] = "OOna";
builder.Form["State"] = "UP";
builder.Form["ZipCode"] = "98456-7329";
builder.Form["PhoneNumber"] = "(425)882-8080";
builder.Form["DateOfBirth"] = "10/28/1987";
builder.Form["PatientDateOfBirth"] = "10/28/1987";
builder.Form["EffectiveDate"] = "01/01/1995";
builder.Form["PatientEffectiveDate"] = "01/01/1995";
PatientController patientController = builder.CreateController<PatientController>();
JsonResult jsonResult = (JsonResult)patientController.AddPatient();
dynamic jsonData = jsonResult.Data;
string jsonMessage=Convert.ToString(jsonData.ReturnMessage);
Assert.AreEqual(jsonData.ReturnStatus, true );
Assert.Greater(jsonData.PatientID, 0);
}
Please give me the solution for my probelm.

You have a null somewhere in patientViewModel. Can you post that type here? This could be a problem with mixing models and view models.

Related

Junit Test failing for Reactive Transaction with Spring-TransactionalOperator

I am using Spring reactive and want transactional behavior in saving data into two different tables. I have used .as(operator::transactional). I am facing issue while doing Unit Testing
DAO Class Code with autowired Repositories & TransactionalOperator:
var transactionDetails = getTransactionDetails(txnDetailsRequest, accountDetailsRequest, httpReqHeaders);
var accountProcessingDetails = getAccountProcessingDetails(accountDetailsRequest);
var response = transactionDetailsRepository.save(transactionDetails)
.then(accountProcessingDetailsRepository.save(accountProcessingDetails))
.onErrorMap(DataAccessException.class, handleDataAccessException)
.onErrorMap(SocketTimeoutException.class, timeOutException)
.as(operator::transactional)
.then(Mono.just("Insertion Successful"));
Test case code:
#Test
public void test() {
TransactionDetails transactionDetails = TestHelper.createTransactionDetails();
when(transactionDetailsRepository.save(any(TransactionDetails.class)))
.thenReturn(Mono.just(transactionDetails));
var accountProcessingDetails = TestHelper.createAccountProcessingDetails();
when(accountProcessingDetailsRepository.save(any(AccountProcessingDetails.class)))
.thenReturn(Mono.just(accountProcessingDetails));
var txnEligibilityRequest = TestHelper.getTransactionsEligibilityRequest();
Map<String, String> headerMap = TestHelper.getHeaderMap();
var responseMono = transactionDetailsDAOImpl.saveTransactionDetails(txnEligibilityRequest.getDataRequest().getTxnDetailsRequestList().get(0),
txnEligibilityRequest.getDataRequest().getAccountDetailsRequest(), headerMap);
StepVerifier.create(responseMono).assertNext(response -> {
assertEquals(response, "Insertion Successful");
}).verifyComplete();
}
While running the test case I'm getting the following error, on the line .then(Mono.just("Insertion Successful"));:
java.lang.NullPointerException: Cannot invoke "reactor.core.publisher.Mono.then(reactor.core.publisher.Mono)" because the return value of "reactor.core.publisher.Mono.as(java.util.function.Function)" is null
Can someone help in this issue:
What's wrong in the current code?
How to mock the org.springframework.transaction.reactive.TransactionalOperator object?

The best way to modify a WebAPI OData QueryOptions.Filter

I am using the OData sample project at http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/working-with-entity-relations. In the Get I want to be able to change the Filter in the QueryOptions of the EntitySetController:
public class ProductsController : EntitySetController<Product, int>
{
ProductsContext _context = new ProductsContext();
[Queryable(AllowedQueryOptions=AllowedQueryOptions.All)]
public override IQueryable<Product> Get()
{
var products = QueryOptions.ApplyTo(_context.Products).Cast<Product>();
return products.AsQueryable();
}
I would like to be able to find properties that are specifically referred to. I can do this by parsing this.QueryOptions.Filter.RawValue for the property names but I cannot update the RawValue as it is read only. I can however create another instance of FilterQueryOption from the modified RawValue but I cannot assign it to this.QueryOptions.Filter as this is read only too.
I guess I could call the new filter's ApplyTo passing it _context.Products, but then I will need to separately call the ApplyTo of the other properties of QueryOptions like Skip and OrderBy. Is there a better solution than this?
Update
I tried the following:
public override IQueryable<Product> Get()
{
IQueryable<Product> encryptedProducts = _context.Products;
var filter = QueryOptions.Filter;
if (filter != null && filter.RawValue.Contains("Name"))
{
var settings = new ODataQuerySettings();
var originalFilter = filter.RawValue;
var newFilter = ParseAndEncyptValue(originalFilter);
filter = new FilterQueryOption(newFilter, QueryOptions.Context);
encryptedProducts = filter.ApplyTo(encryptedProducts, settings).Cast<Product>();
if (QueryOptions.OrderBy != null)
{
QueryOptions.OrderBy.ApplyTo<Product>(encryptedProducts);
}
}
else
{
encryptedProducts = QueryOptions.ApplyTo(encryptedProducts).Cast<Product>();
}
var unencryptedProducts = encryptedProducts.Decrypt().ToList();
return unencryptedProducts.AsQueryable();
}
and it seems to be working up to a point. If I set a breakpoint I can see my products in the unencryptedProducts list, but when the method returns I don't get any items. I tried putting the [Queryable(AllowedQueryOptions=AllowedQueryOptions.All)] back on again but it had no effect. Any ideas why I am not getting an items?
Update 2
I discovered that my query was being applied twice even though I am not using the Queryable attribute. This meant that even though I had items to return the List was being queried with the unencrypted value and therefore no values were being returned.
I tried using an ODataController instead:
public class ODriversController : ODataController
{
//[Authorize()]
//[Queryable(AllowedQueryOptions = AllowedQueryOptions.All)]
public IQueryable<Products> Get(ODataQueryOptions options)
{
and this worked! Does this indicate that there is a bug in EntitySetController?
You would probably need to regenerate ODataQueryOptions to solve your issue. Let's say if you want to modify to add $orderby, you can do this like:
string url = HttpContext.Current.Request.Url.AbsoluteUri;
url += "&$orderby=name";
var request = new HttpRequestMessage(HttpMethod.Get, url);
ODataModelBuilder modelBuilder = new ODataConventionModelBuilder();
modelBuilder.EntitySet<Product>("Product");
var options = new ODataQueryOptions<Product>(new ODataQueryContext(modelBuilder.GetEdmModel(), typeof(Product)), request);

Linq in C# using IEnumerable

Appearently, I got an error if using the following code. It said:
Cannot implicity converrt type System.Linq.IQueryable<AnonymousType> to System.Collection.Generic.IEnumerable.
Please advise how I can fix this?
public IEnumerable<Session> GetAllListDetailConsumer(string refId)
{
ObjectQuery<Session> sessions = db.Sessions;
ObjectQuery<SessionsList> sessionsLists = db.SessionsList;
var query =
from s in sessions
join sList in sessionsLists on s.ReferralListID equals sList.ReferralListID
where s.ReferralListID == new Guid(refId)
select new SessionConsumerList
{
ReferralListID = s.ReferralListID,
SessionServerId = s.SessionServerID,
ApplicationID = s.ApplicationID,
// ...
ConsumerID = sList.ConsumerID,
ConsumerFirstName = sList.ConsumerFirstName,
ConsumerFamilyName = sList.ConsumerFamilyName,
// ...
};
return query.ToList();
}
You are selecting using select new, which would create an anonymous type, you need to project to class Session in your query like.
select new Session
{
....
But remember if your Session class is a representing a table in your database/data context, then you can't project to that class, instead you may have to create a temporary class and project the selection to that class.
EDIT (Since the question now has been edited)
Now you are selecting new SessionConsumerList and you are returning IEnumerable<Session>, you need to modify method signature to return IEnumerable<SessionConsumerList>
Why not separate the creation of the SessionConsumerList in another method? Makes the code a lot cleaner. Like this:
public static SessionConsumerList CreateSessionConsumerList(
Session s,
SessionsList sList)
{
return new SessionConsumerList
{
ReferralListID = s.ReferralListID,
SessionServerId = s.SessionServerID,
ApplicationID = s.ApplicationID,
// ...
ConsumerID = sList.ConsumerID,
ConsumerFirstName = sList.ConsumerFirstName,
ConsumerFamilyName = sList.ConsumerFamilyName,
// ...
};
}
And then:
var query =
from s in sessions
join sList in sessionsLists on s.ReferralListID equals sList.ReferralListID
where s.ReferralListID == new Guid(refId)
select CreateSessionConsumerList(s, sList);

Twitterizer get user information

I have a questions on using Twitterizer
I want to get the TwitterUser model for getting the user's information from the response request on Twitter, but i don't know the way.
This is my code:
public ActionResult Logon(string oauth_token, string oauth_verifier, string ReturnUrl)
{
if (string.IsNullOrEmpty(oauth_token) || string.IsNullOrEmpty(oauth_verifier))
{
UriBuilder builder = new UriBuilder(this.Request.Url);
builder.Query = string.Concat(
builder.Query,
string.IsNullOrEmpty(builder.Query) ? string.Empty : "&",
"ReturnUrl=",
ReturnUrl);
string token = OAuthUtility.GetRequestToken(
ConfigurationManager.AppSettings["TwitterConsumerKey"],
ConfigurationManager.AppSettings["TwitterConsumerSecret"],
builder.ToString()).Token;
//return Redirect(OAuthUtility.BuildAuthorizationUri(token, true).ToString());
Response.Redirect(string.Format("http://twitter.com/oauth/authenticate?oauth_token={0}&force_login=true", token), true);
}
var tokens = OAuthUtility.GetAccessToken(
ConfigurationManager.AppSettings["TwitterConsumerKey"],
ConfigurationManager.AppSettings["TwitterConsumerSecret"],
oauth_token,
oauth_verifier);
OAuthTokens accessToken = new OAuthTokens();
accessToken.AccessToken = tokens.Token;
accessToken.AccessTokenSecret = tokens.TokenSecret;
accessToken.ConsumerKey = ConfigurationManager.AppSettings["TwitterConsumerKey"];
accessToken.ConsumerSecret = ConfigurationManager.AppSettings["TwitterConsumerSecret"];
//TwitterUser u =
TwitterUser myTwitterUser = ..............
..............
}
I already get the OAuthTokens.After the "........." i don't know what to do next to get the information for the user.
Anyone can help me.Thansk a lot
Did you try looking at the documentation:
TwitterResponse<TwitterUser> myTwitterUser = TwitterUser.Show(accessToken, "twit_er_izer");

How to change AzureADOptions at runtime

I am trying to change AzureADOptis at run time. I tried the following, but after this, clicking on the sign in link takes old values for redirecting it to microsoft login page. Expectation is to take updated options.
var options = new AzureADOptions
{
Instance = "https://login.microsoftonline.com/",
Domain = "....",
TenantId = "....",
ClientId = "....",
CallbackPath = "/signin-oidc"
};
_optionsCache.TryRemove(AzureADDefaults.AuthenticationScheme);
_optionsCache.TryAdd(AzureADDefaults.AuthenticationScheme, options);
You can use OpenIdConnectOptions since AzureADOptions will also map to OpenIdConnectOptions in library . And you need to inject OpenIdConnectPostConfigureOptions into DI system and call _postConfigureOptions.PostConfigure before _optionsCache.TryAdd :
ConfigureServices.cs:
services.AddSingleton<OpenIdConnectPostConfigureOptions>();
In your Controller:
private readonly IAuthenticationSchemeProvider _schemeProvider;
private readonly IOptionsMonitorCache<OpenIdConnectOptions> _optionsCache;
private readonly OpenIdConnectPostConfigureOptions _postConfigureOptions;
public HomeController(IAuthenticationSchemeProvider schemeProvider, IOptionsMonitorCache<OpenIdConnectOptions> optionsCache, OpenIdConnectPostConfigureOptions postConfigureOptions)
{
_schemeProvider = schemeProvider;
_optionsCache = optionsCache;
_postConfigureOptions = postConfigureOptions;
}
In your action :
var OIDCoptions = new OpenIdConnectOptions
{
Authority = "https://login.microsoftonline.com/YourTenantID/",
ClientId = "YourClientID",
CallbackPath = "/signin-oidc"
};
_postConfigureOptions.PostConfigure(AzureADDefaults.OpenIdScheme, OIDCoptions);
_optionsCache.TryRemove(AzureADDefaults.OpenIdScheme);
_optionsCache.TryAdd(AzureADDefaults.OpenIdScheme, OIDCoptions);

Resources