I'm trying to unit test my controller which contains a check for ModelState.IsValid but for some reason whatever I do I always end up with an null exception everywhere I try to access the ModelState (both in unit test and controller function).
Everywhere I check people just use the ModelState.Clear()/.AddModelError() and it seems to work for them. Some have said that they get an exception when the mvc versions differ but I have checked that and they were the same.
What can I be missing?
Heres the unit test code:
private Mock<IRegistrationService> registrationService;
private RegistrationController registrationCtrl;
public RegisteringANewUser()
{
registrationService = new Mock<IRegistrationService>();
registrationCtrl = new RegistrationController(registrationService.Object);
registrationCtrl.ModelState.Clear(); <- throws exception
}
[Fact]
public void ShouldRegisterUser_WhenInputIsCorrect()
{
var registration = RegistrationHelper.CreateRegistrationVM("username", "password", "asfa#asf.com");
registrationCtrl.Post(registration);
registrationService.Verify(s => s.Register(registration), Times.Once);
}
[Fact]
public void ShouldReturnBadRequest_WhenInputIsInvalid()
{
var registration = RegistrationHelper.CreateRegistrationVM("", "", "");
registrationCtrl.ModelState.AddModelError("Error", "Error"); <- throws exception
var result = registrationCtrl.Post(registration);
Assert.Equal((int)HttpStatusCode.BadRequest, result.StatusCode);
}
The controller function under test:
public HttpStatusCodeResult Post(RegistrationVM registration)
{
if (!ModelState.IsValid) <- throws exception
{
return new HttpStatusCodeResult((int)HttpStatusCode.BadRequest);
}
_registrationService.Register(registration);
return new HttpStatusCodeResult((int)HttpStatusCode.OK);
}
project.json for unit test library:
{
"version": "1.0.0-*",
"dependencies": {
"Web": "1.0.0-*",
"Moq": "4.2.1409.1722",
"Xunit.KRunner": "1.0.0-rc1-10618",
"Microsoft.AspNet.Mvc": "6.0.0-beta1"
},
"frameworks": {
"aspnet50": {
"dependencies": {
}
}
},
"commands": {
"test": "Xunit.KRunner"
}
}
And for the web site project:
{
/* Click to learn more about project.json http://go.microsoft.com/fwlink/?LinkID=517074 */
"webroot": "wwwroot",
"version": "1.0.0-*",
"dependencies": {
"Microsoft.AspNet.Mvc": "6.0.0-beta1",
//"Microsoft.AspNet.Mvc.WebApiCompatShim": "6.0.0-beta1",
"Microsoft.AspNet.Diagnostics": "1.0.0-beta1",
"Microsoft.AspNet.Security.Cookies": "1.0.0-beta1",
"Microsoft.AspNet.Server.IIS": "1.0.0-beta1",
"Microsoft.AspNet.Server.WebListener": "1.0.0-beta1",
"Microsoft.AspNet.StaticFiles": "1.0.0-beta1",
"Microsoft.Framework.ConfigurationModel.Json": "1.0.0-beta1",
"Microsoft.Framework.CodeGenerators.Mvc": "1.0.0-beta1",
"Microsoft.Framework.Logging": "1.0.0-beta1",
"Microsoft.Framework.Logging.Console": "1.0.0-beta1",
"Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0-beta1",
"mongocsharpdriver": "1.10.0.0-rc1"
},
"commands": {
/* Change the port number when you are self hosting this application */
"web": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener --server.urls http://localhost:5000",
"gen": "Microsoft.Framework.CodeGeneration"
},
"frameworks": {
"aspnet50": { },
"aspnetcore50": { } <- tried to remove this as I dont have it in my unit test lib without success
},
"exclude": [
"wwwroot",
"node_modules",
"bower_components"
],
"packExclude": [
"node_modules",
"bower_components",
"**.kproj",
"**.user",
"**.vspscc"
],
"scripts": {
"postrestore": [ "npm install" ],
"prepare": [ "grunt bower:install" ]
}
}
This was indeed a gap (until beta3). Was tracked by this Issue
In Beta3 release (or you can just get at the dev builds in a day or so), we are going to initialize a unit testing only ViewDataDictionary so that your unit test will get an empty ModelState.
Here is a the new code snippet from Controller.cs
[Activate]
public ViewDataDictionary ViewData
{
get
{
if (_viewData == null)
{
// This should run only for the controller unit test scenarios
_viewData =
new ViewDataDictionary(new EmptyModelMetadataProvider(),
ActionContext?.ModelState ?? new ModelStateDictionary());
}
return _viewData;
}
set
{
if (value == null)
{
throw
new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(ViewData));
}
_viewData = value;
}
}
And (no change to the code)
public ModelStateDictionary ModelState
{
get
{
return ViewData?.ModelState;
}
}
Related
I am having a problem getting data in android from atlas mongoDB (stitch):
service not found: 'mongodb-atlas'
StitchError: service not found: 'mongodb-atlas'
{
"arguments": [
{
"database": "vutuduDB",
"collection": "test",
"query": {},
"limit": {
"$numberInt": "0"
},
"project": null,
"sort": null
}
],
"name": "find",
"service": "mongodb-atlas"
}
Also when I tried to create a http service and use the console I got the same problem while running the line:
context.services.get("mongodb-atlas");
Java code:
public class SearchFragment extends Fragment {
Button btnSearch;
private StitchAppClient stitchClient;
private RemoteMongoClient mongoClient;
private RemoteMongoCollection itemsCollection;
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View layout = inflater.inflate(R.layout.search_fragment_layout, container, false);
this.stitchClient = Stitch.getDefaultAppClient();
Log.d("stitch", "logging in anonymously");
stitchClient.getAuth().loginWithCredential(new AnonymousCredential()
).continueWithTask(new Continuation<StitchUser, Task<Void>>() {
#Override
public Task<Void> then(#NonNull Task<StitchUser> task) throws Exception {
if (task.isSuccessful()) {
Log.d("stitch", "logged in anonymously as user " + task.getResult());
} else {
Log.e("stitch", "failed to log in anonymously", task.getException());
}
mongoClient = stitchClient.getServiceClient(RemoteMongoClient.factory, "mongodb-atlas");
RemoteMongoDatabase db = mongoClient.getDatabase("vutuduDB");
Log.d("stitch", "GETTING ITEMS");
db.getCollection("test").find().forEach(item -> Log.d("ITEM: ", item.toString()));
return null;
}
});
return layout;
}
}
I have a simple POST request sending params using application/x-www-form-urlencoded encoding.
Looking in the wiremock docs I can't find a way to match the request by the params values, something like the querystring match I mean.
Furthermore it seems also impossible to contains for the body, nor to match the entire body in clear (just as base64).
Is there a way to match this kind of requests?
Another option that I found was to use contains for Stubbing Content-Type: application/x-www-form-urlencoded
{
"request": {
"method": "POST",
"url": "/oauth/token",
"basicAuthCredentials": {
...
},
"bodyPatterns": [
{
"contains": "username=someuser"
}
]
},
"response": {
....
}
}
With classic wiremock you can use bodyPatterns' matchers and regular expressions:
for example:
...
"request": {
"method": "POST",
"url": "/api/v1/auth/login",
"bodyPatterns": [
{
"matches": "(.*&|^)username=test($|&.*)"
},
{
"matches": "(.*&|^)password=123($|&.*)"
}
]
},
I had a similar problem - I wanted to check the exact parameters , but without patterm magic (so easier to maintain). As a workaround, I created a helper class :
import java.util.Iterator;
import java.util.LinkedHashMap;
public class WireMockUtil {
public static String toFormUrlEncoded(LinkedHashMap<String, String> map) {
if (map == null) {
return "";
}
StringBuilder sb = new StringBuilder();
Iterator<String> it = map.keySet().iterator();
while (it.hasNext()) {
String key = it.next();
String value = map.get(key);
appendFormUrlEncoded(key,value,sb);
if (it.hasNext()) {
sb.append('&');
}
}
return sb.toString();
}
public static String toFormUrlEncoded(String key, String value) {
StringBuilder sb = new StringBuilder();
appendFormUrlEncoded(key, value,sb);
return sb.toString();
}
public static void appendFormUrlEncoded(String key, String value, StringBuilder sb) {
sb.append(key).append('=');
if (value != null) {
sb.append(value);
}
}
}
Inside the Wiremock test you can use it via:
LinkedHashMap<String, String> map = new LinkedHashMap<>();
map.put("key1", "value1");
map.put("key2", "value2");
...
withRequestBody(equalTo(WireMockUtil.toFormUrlEncoded(map))).
Or check only dedicated parts by containing:
withRequestBody(containing(WireMockUtil.toFormUrlEncoded("key","value1"))).
You could try https://github.com/WireMock-Net/WireMock.Net
Matching query parameters and body can be done with this example json:
{
"Guid": "dae02a0d-8a33-46ed-aab0-afbecc8643e3",
"Request": {
"Url": "/testabc",
"Methods": [
"put"
],
"Params": [
{
"Name": "start",
"Values": [ "1000", "1001" ]
},
{
"Name": "end",
"Values": [ "42" ]
}
],
"Body": {
"Matcher": {
"Name": "WildcardMatcher",
"Pattern": "test*test"
}
}
}
}
I'm working on a netcoreapp1.0 application , ( my target framework is netcoreapp1.0), i want to create a windows service from this application, lets say it is running every 5 minutes.
The package to use for creating ws is this one, but this package only works on full .net framework which is not appropriate for me, I want a solution which works for .netcoreapp1.0 only.
Is there any solution for my problem?
here is my project.json file :
{
"version": "1.0.0-*",
"buildOptions": {
"emitEntryPoint": true
},
"frameworks": {
"netcoreapp1.0": {
}
},
"dependencies": {
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.0"
},
"Microsoft.AspNetCore.Hosting": "1.0.0",
"Microsoft.AspNetCore.Hosting.WindowsServices": "1.0.0",
"Microsoft.AspNetCore.Server.Kestrel": "1.0.0"
}
}
and here is my program.cs:
public class Program
{
public static void Main(string[] args)
{
var exePath = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
var directoryPath = Path.GetDirectoryName(exePath);
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(directoryPath)
.UseStartup<Startup>()
.Build();
if (Debugger.IsAttached || args.Contains("--debug"))
{
host.Run();
}
else
{
host.RunAsService();
}
}
}
I have an ASP .NET MVC 6 and Entity Framework 6, divided into layers , how do I get the connection string in the DAL layer in my DbContext ?
The connection string is in appsettings.json file like this:
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Verbose",
"System": "Information",
"Microsoft": "Information"
}
},
"Data": {
"DefaultConnection": {
"ConnectionString": "",
}
}
}
If you have the connection string in appsettings.json you want to build a configuration object first:
var builder = new ConfigurationBuilder().AddJsonFile("appsettings.json");
var configuration = builder.Build();
This should probably be in Startup's ctor. You can then store the configuration object in a field. Let's say a _configuration field.
Then you can do
// _connectionString is also a field.
_connectionString = _configuration["Data:DefaultConnection"];
Your DbContext:
public class AppDbContext : DbContext
{
public AppDbContext(string connectionString) : base(connectionString)
{
}
}
The you can register your AppDbContext in ConfigureServices as:
services.AddScoped(_ => new AppDbContext(_connectionString));
I am getting the values of some datatypes in umbraco to my MVC view in cshtml I am getting a result in JSON how will I parse the JSON to bind it to a drop down list. What are the possible methods to do this. I have installed NetonSoft JSON in project also
if (home.GetProperty("residentsLogin") != null && !string.IsNullOrEmpty(home.GetPropertyValue("residentsLogin")))
{
var residentslog = home.GetPropertyValue("residentsLogin");
}
My JSON is in the corresponding format
[
{
"name": "Property1",
"url": "http://www.google.com",
"target": "_blank",
"icon": "icon-link"
},
{
"name": "Property2",
"url": "http://www.google.com",
"target": "_blank",
"icon": "icon-link"
}
]
Working code should look like this:
public class MyJsonObject
{
public string name{get;set;}
public string url { get; set; }
public string target { get; set; }
public string icon { get; set; }
}
var residentslog = #"[
{
'name': 'Property1',
'url': 'http://www.google.com',
'target': '_blank',
'icon': 'icon-link'
},
{
'name': 'Property2',
'url': 'http://www.google.com',
'target': '_blank',
'icon': 'icon-link'
}
]";
List<MyJsonObject> myJsonObjectList = JsonConvert.DeserializeObject<List<MyJsonObject>>(residentslog);
ViewBag.MySelectList = new SelectList(myJsonObjectList, "name", "url");