JsonDocument Parse JsonReaderException - xUnit - asp.net-core

I thought I found a cleaner way with a smaller footprint to test a string to see if its valid JSON; however when I run a test its failing because its returns a JsonReaderException so when I tried to change the type to this, I get a protection error as it seems to be internal??
I am using System.Text.Json in my project.
How can this be changed so I can use my existing code:
public ApplicationSettings WithTemplate(string template) {
try {
JsonDocument.Parse(template);
baseTemplate = template;
}
catch(JsonException ex) {
throw ex;
}
return this;
}
Test Code:
[Fact]
public void WithTemplate_ThrowsJsonExceptionWhenBaseTemplateIsInvalid() {
Assert.Throws<JsonException>(() => new ApplicationSettings()
.WithTemplate("345[]{}q345"));
}

I found a solution that was just as compact as JsonDocument.Parse() for just checking the validity of string of json with the JsonSerializer.
string malformedJson = "345[]{}q345"
JsonSerializer.Deserialize<object>(malformedJson)
Then I was able to test against the exception JsonException and not have to worry about JsonReaderException

Related

ASP.NET Core 7 WebApplicationFactory Integration tests. How to load data?

I am creating an integration test to check that the data is working based on this very good tutorial.
The tutorial loads sample data in the OnModelCreating. But I was unsure if doing that will repeatedly load data to the DB when running the program.
However although I can get the index page to load, it has the page content, such as the table structure for the data it doesn't have the data from the database.
Using Swagger I copied a sample of data as JSON, saved it to a file, capitalized the first letter of the key to make it the same as the properties (after not doing do was fruitless as well), and tried to add it to the context.
internal static class AddTestData
{
//import json array and add to context
public static void AddMovieData(ApplicationDbContext context)
{
var jsonString = File.ReadAllText("testMoviedata.json");
var list = JsonSerializer.Deserialize<List<Movie>>(jsonString);
{
foreach (var item in list)
{
context.Movie.Add(item);
}
context.SaveChanges();
}
}
}
and tried to add it to the dbcontext in this process in the WebApplicationFactory Class from HERE
public class TestingWebAppFactory<TEntryPoint> : WebApplicationFactory<Program> where TEntryPoint : Program
{
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.ConfigureServices(services =>
{
......... stuff deleted for brevity...
using (var appContext = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>())
{
try
{
appContext.Database.EnsureCreated();
// Seed the database with test data.
AddTestData.AddMovieData(appContext);
}
catch (Exception ex)
{
//Log errors or do anything you think it's needed
throw;
}
}
... still nothin. Page loads, no data loads.
Also why can't I get breakpoints to work in the Integration project?
What am I doing wrong?
Solved!!!
The code was OK,but the data wasn't being deserialised.
I had to move it to the main project and test it there.
The solution is
var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};
var list = JsonSerializer.Deserialize<Movie[]>(jsonString, options);

Cucumber JVM: Test if the correct exception is thrown

How to test that the correct exception is thrown when using Cucumber JVM? When using JUnit, I would do something like this:
#Test(expected = NullPointerException.class)
public void testExceptionThrown(){
taskCreater.createTask(null);
}
As you can see, this is very elegant. But how can I achieve the same elegance, when using cucumber JVM? My test looks like this right now:
#Then("the user gets a Null pointer exception$")
public void null_exception_thrown() {
boolean result = false;
try {
taskCreater.createTask(null);
} catch (NullPointerException e) {
result = true;
}
assertTrue(result);
}
Note the need for a try..catch followed by an assertTrue on a flag.
Testing the not-happy-path can be hard. Here's a nice way that I've found to do it with cucumber.
Scenario: Doing something illegal should land you in jail
Then a failure is expected
When you attempt something illegal
And it fails.
OK, don't shoot me because I put the Then before the When, I just think it reads better but you don't have to do that.
I store my excepions in a (cucumber-scoped) world object, but you could also do it in your step file, but this will limit you later.
public class MyWorld {
private boolean expectException;
private List<RuntimeException> exceptions = new ArrayList<>();
public void expectException() {
expectException = true;
}
public void add(RuntimeException e) {
if (!expectException) {
throw e;
}
exceptions.add(e);
}
public List<RuntimeException> getExceptions() {
return exceptions;
}
}
Your steps are then pretty simple:
#Then("a failure is expected")
public void a_failure_is_expected() {
myWorld.expectException();
}
In a step where you are (at least sometimes) expecting an exception, catch it and add it to the world.
#When("you attempt something illegal")
public void you_attempt_something_illegal() {
try {
myService.doSomethingBad();
} catch (RuntimeException e) {
world.add(e);
}
}
Now you can check whether the exception was recorded in the world.
#And("it fails")
public void it_fails() {
assertThat(world.getExceptions(), is(not(empty()));
}
The most valuable thing about this approach is that it won't swallow an exception when you don't expect it.
Have you tried using the junit #Rule annotation with ExpectedException, like this:
#Rule
public ExpectedException expectedEx = ExpectedException.none();
#Then("the user gets a Null pointer exception$")
public void null_exception_thrown() {
expectedEx.expect(NullPointerException.class);
//expectedEx.expectMessage("the message");
taskCreater.createTask(null);
}
Behaviour testing verifies if your project follows specifications, and I doubt the user expects a NullPointerException while using the system.
In my opinion (I'm not familiar with your project), exceptions should only be checked during Unit Tests, as they correspond to an unexpected error or user mistake.
It's very unusual to check for exceptions during behaviour tests. If an exception is thrown during a test, it should fail.
for instance:
test.feature
Given that I have a file "users.txt"
And I try to import users /* If an Exception is thrown here, the test fails */
Then I should see the following users: /* list of users */
In my unit test, I would have:
#Test(expected = MyException.class)
public void importUsersShouldThrowMyExceptionWhenTheFileIsNotFound() {
// mock a call to a file and throw an exception
Mockito.when(reader.readFile("file.txt").thenThrow(new FileNotFoundException());
importer.importUsers();
}
I suggest you to use org.assertj.assertj-core.
Thanks to Assertions class, you could simplify your assertion like bellow:
#Then("the user gets a Null pointer exception$")
public void null_exception_thrown() {
Assertions.assertThatThrownBy(() -> taskCreater.createTask(null)).
isInstanceOf(NullPointerException.class);
}
Never used Cucumber, but would
public void null_exception_thrown() {
try {
taskCreater.createTask(null);
fail("Null Pointer Expected");
} catch (NullPointerException e) {
// Do Nothing
}
}
work for you?
I believe Cucumber is meant to test higher level acceptance tests than lower level unit tests as in that case we will be testing the structure opposed to the behavior which is not the desired usage of the Cucumber framework.
i used to have expected exception name in feature steps. for a calculator test example
Here is my feature file entry for division exception :
Scenario: Dividing a number with ZERO
Given I want to test calculator
When I insert 5.5 and 0.0 for division
Then I got Exception ArithmeticException
So, you may see, I have added the exception name. So, in step definition , i get the name of the exception.
Now, we need to get the exception when dividing by ZERO and put in a variable.
And get this variable to compare its class name(exception name)
so, in step definition where i divide by zero
private Exception actualException;
#When("^I insert (.+) and (.+)for division$")
public void iInsertAndForDivision(double arg0, double arg1) throws Throwable {
try {
result = calculator.div(arg0, arg1);
} catch (Exception e) {
actualException =e;
}
}
And i need the step definition for validating the exception
#Then("^I got Exception (.+)")
public void iGotArithmeticException(String aException) throws Throwable {
Assert.assertEquals("Exception MissMatch",aException,actualException.getClass().getSimpleName());
}
The complete project can be seen here : Steps for cucumber

Using Enterpise Library 6 Exception Handling Application Block with WCF?

I have these three packages loaded to my WCF service project:
EnterpriseLibrary.Common Version 6.0.1304.0
EnterpriseLibrary.ExceptionHandling 6.0.1304.0
EnterpriseLibrary.ExceptionHandling.WCF Version 6.0.1304.0
Here is the service interface and MyTestFault DataContract:
[ServiceContract]
public interface IRepairService
{
[OperationContract]
[FaultContract(typeof(MyTestFault))]
string SaveRepairCode(string failureCode, string description);
}
[DataContract]
public class MyTestFault
{
#region Member Fields
private string _message = "An unexpected error occured while executing the service method.";
#endregion
#region Properties
[DataMember]
public string Message
{
get { return _message; }
set { _message = value; }
}
#endregion
#region Constructor(s)
public MyTestFault() { }
#endregion
}
Here is the implementation of the service:
[ExceptionShielding("TestPolicy")]
public class RepairService : IRepairService
{
#region Private members
private WimDAL wimDAL;
ExceptionManager exManager;
#endregion
#region Constructor(s)
public RepairService()
{
wimDAL = new WimDAL();
var testPolicy = new List<ExceptionPolicyEntry>
{
{
new ExceptionPolicyEntry(
typeof(SqlException),
PostHandlingAction.ThrowNewException,
new IExceptionHandler[]
{
new FaultContractExceptionHandler(
typeof(MyTestFault),
"SqlException Occurred.",
new NameValueCollection(){ { "Message", "Message" }})
})
},
{
new ExceptionPolicyEntry(
typeof(Exception),
PostHandlingAction.ThrowNewException,
new IExceptionHandler[]
{
new FaultContractExceptionHandler(
typeof(MyTestFault),
"Exception Occurred.",
new NameValueCollection(){ { "Message", "Message" }})
})
}
};
var policies = new List<ExceptionPolicyDefinition>();
policies.Add(new ExceptionPolicyDefinition(
"TestPolicy", testPolicy));
exManager = new ExceptionManager(policies);
}
#endregion
/// <summary>
/// Insert a new fail code with description into RPCODE.
/// Duplicate primary key will throw SqlException that should be processed by EHAB
/// </summary>
public string SaveRepairCode(string failureCode, string description)
{
using (TransactionScope txScope = new TransactionScope())
{
WimSQLCommand sc = new WimSQLCommand() { StoredProcedure = "Repair.RPCODE_Insert" };
sc.Parameters.Add(new SqlParameter("#FailureCode", failureCode));
sc.Parameters.Add(new SqlParameter("#Desc", description));
exManager.Process(() => wimDAL.Execute_NonQueryNoReturn(sc), "TestPolicy");
txScope.Complete();
return "<Save_Repair_Code></Save_Repair_Code>";
}
}
}
Now, I have a TestClient console application that is part of the same project that has a reference to the project and a service reference. From there I call the SaveRepairCode() method and try to catch the specific fault exception like so:
ServiceReference1.RepairServiceClient r = new ServiceReference1.RepairServiceClient();
Console.WriteLine("Enter a new repair code:");
string repairCode = Console.ReadLine();
Console.WriteLine("Enter description:");
string description = Console.ReadLine();
try
{
r.SaveRepairCode(repairCode, description);
}
catch (FaultException<MyTestFault> ex)
{
//do something
throw;
}
catch (FaultException fex)
{
//do something
throw;
}
Finally, I run the console app and try to save a duplicate repair code. I know through debugging that this causes the SqlException to occur. After I step over the SqlException, I see the "FaultContractWrapperException was unhandled by user code" exception and it has the message I specified in the policy of "SqlException occurred.". When I step over that I get back to the client and see this error:
CommunicationException was unhandled
The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.
PS - this is Enterprise Library 6 with WCF and I made no manual changes to the web.config... and yes, includeExceptionDetailInFaults is set to false.
What am I missing here? Thanks in advance.
UPDATE
Looks like I was missing this one line of code after instantiating the new ExceptionManager.
ExceptionPolicy.SetExceptionManager(exManager);
Nice to see that this one line of code is NOT in the Enterprise Library 6 - April 2013.chm but it IS in the "Developer's Guide to Microsoft Enterprise Library-Preview.pdf" on page 90 of 269. After including that one line I get into the proper FaultException catch on the client.
With that being said, I still can't get other MyTestFault properties on the client. For example, if I add public string StoredProcedureName to MyTestFault and map it to the SqlException's "Procedure" property, I always see null on the client. The only change in the policy for this would be to add the mapping like so:
new NameValueCollection(){ { "Message", "{Message}" }, { "StoredProcedureName", "{Procedure}" } }
It turns out this line was the culprit.
exManager.Process(() => wimDAL.Execute_NonQueryNoReturn(sc), "TestPolicy");
Insead of using the ExceptionManager's Process method, just execute the command you expect a potential exception for like so.
wimDAL.Execute_NonQueryNoReturn(sc);
This does not follow what the "Developer's Guide to Microsoft Enterprise Library-Preview.pdf" says but I guess the documentation is still a work in progress. I hope this helps someone else.

How to catch test failure in Selenium Webdriver using JUnit4?

I need to write the testcase Pass/Fail status in an Excel report. How do I catch the result in a simple way? In Ant XML/HTML reports status (Success/Failed) is displayed so I believe there must be some way to catch this..may be in the #After Class.
Can anyone help me out with this?
I am using Selenium Webdriver with JUnit4 and using Apache POI(oh its screwing my mind too!) for excel handling. Let me know in case you need more info.
Thanks :)
P.S: As I am asking a lot of questions it would be great if someone can change or suggest me changes to make these questions and threads helpful for others.
I got your problem and this is what I have do in all my test cases now -
In your test case if you want to check if 2 Strings are equal -
You might be using this code -
Assert.assertTrue(value1.equals(value2));
And if these values are not equal an AssertionError is generated.
Instead you can change your code like this -
String testCaseStatus = "";
if(value1.equals(value2)){
testCaseStatus = "success";
}
else{
testCaseStatus = "fail";
}
Now you store this result in your excel sheet by passing the testCaseStatus to your code which adds a line to your excel which you have implemented using Apache POI. You can also handle the conditions of "error" if you implement a try catch block.
For example you can catch some exception and add the status as error to your excel sheet.
Edited part of answer -
I just figured out on how to use the TestResult class -
This is some sample code I'm posting -
This is the test case class called ExampleTest -
public class ExampleTest implements junit.framework.Test {
#Before
public void setUp() throws Exception {
}
#After
public void tearDown() throws Exception {
}
#Test
public void test(TestResult result) {
try{
Assert.assertEquals("hari", "");
}catch(AssertionFailedError e){
result.addFailure(this, e);
}catch(AssertionError e){
result.addError(this, e);
}
}
#Override
public int countTestCases() {
// TODO Auto-generated method stub
return 0;
}
#Override
public void run(TestResult result) {
test(result);
}
}
I call the above test case from this code -
public class Test {
public static void main(String[] args) {
TestResult result = new TestResult();
TestSuite suite = new TestSuite();
suite.addTest(new ExampleTest());
suite.run(result);
System.out.println(result.errorCount());
}
}
You can call many test cases by just adding them to this suite and then get the entire result using the TestResult class failures() and errors() methods.
You can read more on this from here.

FaultException.Detail coming back empty

I am trying to catch a given FaultException on a WCF client. I basically need to extract a inner description from the fault class so that I can then package it in another exception for the upper layers to do whatever.
I've done this successfully a number of time, what makes it different this time is that fault is declared as an array, as you can see from the service reference attribute declared on top of the method that throws the exception:
[System.ServiceModel.FaultContractAttribute(typeof(FaultClass[]), Action = "http://whatever/", Name = "whateverBusinessFault")]
This is my code:
try
{
// call service here
}
catch (FaultException<FaultClass[]> ex)
{
if (ex.Detail != null && ex.Detail.Length > 0)
{
throw new CustomException(ex.Detail[0].description);
}
else
{
throw;
}
}
Problem is Detail (which is an array) is always coming back empty in the code even if I can see the data (description field etc.) in the SOAP response from WCF trace.
So the stuff I need is definitely coming back but for some reason either it doesn't get deserialized or I can't get to it from code.
Any help appreciated!
UPDATE:
Trying with #Darin suggestion but no luck, the string I am extracting from the XmlReader is "/r/n":
var sb = new StringBuilder();
using (XmlReader reader = fault.GetReaderAtDetailContents())
{
while (reader.Read())
sb.AppendLine(reader.ReadOuterXml());
}
var detail = sb.ToString();
Looks like the detail section is not coming up at all!
I found the solution on a UPS Forum :
https://developerkitcommunity.ups.com/index.php/Special:AWCforum/st/id371
"The problem was the visual studio didn't quite map out the ErrorDetail objects right. The ErrorDetail node is called "ErrorDetail", but the type generated for it is "ErrorDetailType." I edited the reference.cs class generated for each service I was using and added a TypeName:"
It is difficult to say where the problem is but I suspect the smoking gun is this axis web service not generating standard message. One way to workaround this would be to parse the XML yourself:
try
{
proxy.CallSomeMethod();
}
catch (FaultException ex)
{
var fault = ex.CreateMessageFault();
using (XmlReader reader = fault.GetReaderAtDetailContents())
{
// TODO: read the XML fault and extract the necessary information.
}
}
It took me ages to figure out how to get the full details message from a FaultException as a string. I eventually figured it out and wrote this extension method:
public static string GetDetail(this FaultException faultException)
{
if (faultException == null)
throw new ArgumentNullException(nameof(faultException));
MessageFault messageFault = faultException.CreateMessageFault();
if (messageFault.HasDetail) {
using (XmlDictionaryReader reader = messageFault.GetReaderAtDetailContents()) {
return reader.ReadContentAsString();
}
}
return null;
}
Originally I was using reader.Value but that only appeared to the return the first line of a multi-line details message. reader.ReadContentAsString() appears to get the whole thing, new lines included, which is what I wanted.
I came up with the simplest test case I could. I hope it will help you.
Server side:
[ServiceContract]
public interface IService1
{
[OperationContract]
[FaultContract(typeof(FaultClass[]))]
string Crash();
}
public class Service1 : IService1
{
public string Crash()
{
var exception = new FaultException<FaultClass[]>(new FaultClass[] { new FaultClass { Data = "TEST" } }, new FaultReason("Boom"));
throw exception;
}
}
[DataContract]
public class FaultClass
{
[DataMember]
public string Data { get; set; }
}
Client side:
try
{
using (var client = new Service1Client())
{
client.Crash();
}
}
catch(FaultException<FaultClass[]> e)
{
//Break here
}
I had a similar situation in trying to communicate data with faults (specifically a stack trace). See this question. I ended up solving it by creating my own serializable stack trace and including it in a derived FaultException class.