Why does plainToClass not throw for invalid input types - class-transformer

Example:
class Test {
#IsString()
readonly table!: string;
}
// note, that we call it with a completely wrong type: string instead of JSON-object
const result = plainToClass(Test, 'not a class');
Then result is the input string 'not a class'!
I'd expect plainToClass to:
return an instance of type Test where all properties remain undefined, or
throw an exception
Is this a bug or am I missing something?
I also found not option to make this work as expected.
The workround for now is to explicitly typecheck and throw in my own code:
if (!(result instanceof Test) throw ...;
using class-transformer 0.2.3

Related

Asp.net FluentValidation unit testing object as null

I'm doing some unit testing using FluentValidation in Asp.net. I have setup a rule stating that an object is not allowed to be null, as it's going to be used as an argument in a method. The rule is made in a validator-class in the constructor:
//Object itself.
RuleFor(x => x).NotNull();
The unit test looks like (I'm using NUnit):
[Test]
public void RequestObjectIsNull_ExpectError()
{
BusinessRequest request = null;
var result = validator.Validate(request);
Assert.IsFalse(result.IsValid);
}
It fails with the message:
Message: System.ArgumentNullException : Cannot pass null model to Validate.
Parameter name: instanceToValidate
How do I test this?
This question is quite old but I have stumbled upon the same issue. I wanted the fluent validator to validate it for me if it is null and say so and not throw an exception, instead of me explicitly checking for it. I have found a solution of overriding the existing methods, For example:
public class MyValidator : AbstractValidator<MyObject>
{
public MyValidator()
{
RuleSet("MyRule", () =>
{
RuleFor(x=>x.MyProperty=="Something").WithMessage("failed");
});
}
public override Task<ValidationResult> ValidateAsync(ValidationContext<MyObjec>> context, CancellationToken cancellation = default)
{
return context.InstanceToValidate == null ? Task.FromResult(new ValidationResult(new[] { new ValidationFailure("MyObject", "filed with null") })) : base.ValidateAsync(context, cancellation);
}
}

powermock running with MockitToRunner - getting matchers error

#RunWith(MockitoJUnitRunner.class)
public class MessageDataTest {
#InjectMocks
MessageData messageData;
#Test
public void testingMethod() throws Exception {
MessageData data = PowerMockito.spy(messageData); //passing the mocked object for spy
PowerMockito.when(data,"isMessageContains",anyString(),any()).thenReturn(true); // throwing exception here
MessageDataResponse response = messageFormatterData.constructData(messageItems);
assertNotNull(response);
}
}
MessageData.java
private boolean isMessageContains(String name, MessageResponse messageResponse) {
for (::) {
some logic
return true;
}
}
return false;
}
when I run the test case, I'm getting the below error,
org.mockito.exceptions.misusing.InvalidUseOfMatchersException: Misplaced argument matcher detected here
You cannot use argument matchers outside of verification or stubbing. Examples of correct usage of argument matchers: when(mock.get(anyInt())).thenReturn(null); doThrow(new RuntimeException()).when(mock).someVoidMethod(anyObject()); verify(mock).someMethod(contains("foo"))
Also, this error might show up because you use argument matchers with methods that cannot be mocked. Following methods cannot be stubbed/verified: final/private/equals()/hashCode(). Mocking methods declared on non-public parent classes is not supported
I want to mock this private "isMessageContains" to return always true.

Unexpected error when deserializing unknown types with Json.Net

In the following code, I serialize an object using Json.Net. This Json has type names embedded. I then change one of the type names to induce an error (this is a test, I am dealing with a real issue in an existing project). When I deserialize the Json, I expect to get an object back that has a null value for the property with the fiddled type name. Instead the serializer craps out and returns null. Are my expectations correct? Can I change the settings somehow so that I will get a non-null object for my root object? Note that the second error that I get suggests that there is a bug in the serializer.
static public class JsonTest
{
static public void Test()
{
// Create test object
A a = new A
{
MyTest = new MyTest(),
};
// Serialize it.
string json = JsonConvert.SerializeObject(a, new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Auto
});
// Fiddle class name to induce error
json = json.Replace("+MyTest", "+MyTest2");
// Before: {"MyTest":{"$type":"<Namespace>.JsonTest+MyTest, <Assembly>"}}
// After: {"MyTest":{"$type":"<Namespace>.JsonTest+MyTest2, <Assembly>"}}
// Deserialize
A a2 = JsonConvert.DeserializeObject<A>(json, new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Auto,
Error = (object sender, ErrorEventArgs e) =>
{
e.ErrorContext.Handled = true; // Should have only one error: the unrecognized Type
}
});
// A second error occurs: Error = {Newtonsoft.Json.JsonSerializationException: Additional text found in JSON string after finishing deserializing object....
// a2 is null
}
public class A
{
public ITest MyTest { get; set; }
}
public interface ITest { }
public class MyTest : ITest { }
}
Update
This issue has been fixed in Json.NET 10.0.2 in this submission.
Original Answer
This looks to be a bug in Json.NET. If I set JsonSerializerSettings.MetadataPropertyHandling = MetadataPropertyHandling.ReadAhead then the problem goes away:
// Deserialize
A a2 = JsonConvert.DeserializeObject<A>(json, new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Auto,
MetadataPropertyHandling = MetadataPropertyHandling.ReadAhead,
Error = (object sender, Newtonsoft.Json.Serialization.ErrorEventArgs e) =>
{
Debug.WriteLine(e.ErrorContext.Path);
e.ErrorContext.Handled = true; // Should have only one error: the unrecognized Type
}
});
Debug.Assert(a2 != null); // No assert.
However, it should not be necessary to turn on this setting, which enables reading metadata properties including "$type" located anywhere in a JSON object, rather than just as the first property. Most likely it coincidentally fixes the bug since it requires pre-loading the entire JSON object before beginning deserialization.
You could report an issue if you want.
Debugging a bit, the problem seems to be that, because the inner MyTest object cannot be constructed, the exception is caught and handled by JsonSerializerInternalReader.PopulateObject() while populating the outer object A. Because of this, the JsonReader does not get advanced past the inner, nested object, leaving the reader and serializer in an inconsistent state. This accounts for the second exception and the eventual Additional text found in JSON string after finishing deserializing object. Path '' exception.

ViewModelBase.IsInDesignModeStatic Property

I am sure this is a MVVM Light newbie error but I need to ask. I am creating an WPF4 application using the MVVM Light framework and Ninject for DI. In the ViewModelLocator contructor I pass in the ViewModelBase.IsInDesignModeStatic value so I know to create DI with DesignTime data or RunTime data.
I thought that when you opened the MainWindow.xml in the designer ( VS2010 or Blend ) that the property would be True and the constructor would execute and break in debug if I had a breakpoint set. The application runs fine and debugs when ran correctly but I never get designtime data because the property is always false. Also does not seem that the constructor is executing when opened in designer. I have watched Laurent's videos multiple times and I know this does work. Can someone please tell me what they think I must be doing wrong.
Orgbrat
I'm late, but try this when troubleshooting this kind of problem.
You'll need a simple Property to test: Create a "Foo" property (string) in the ViewModel and bind it to the XAML (use a TextBlock for example).
In the ViewModel
In the "Get", return an hard coded string (ex: "Step 1". This will validate the "bindings" are valid.
Remove the "Get" hard code, and in the constructor, put a this.Foo = "Step 2" in the first line, this will validate that the constructor is called
Put a third set where the call is "callbacked", this will check that the GetData is being returned
in the "else" of the if (error != null), put the fourth set, and so on...
Example: Here's my MainViewModel constructor.
public MainViewModel(IDataService dataService)
{
this.Foo = "Step 2";
_dataService = dataService;
_dataService.GetData(
(item, error) =>
{
this.Foo = "Step 3";
if (error != null)
{
// Report error here
return;
}
else
{
this.Foo = "Step 4";
}
});
}
My last bug was that I had put the assignment of the data coming back from the GetData in the "if (error != null){...}" ! So it was never called.
Since then, I rewrite the constructor like this:
public MainViewModel(IDataService dataService)
{
_dataService = dataService;
_dataService.GetData(
(item, error) =>
{
if (error == null)
{
// Normal code here
return;
}
else
{
// Report error here
return;
}
});
}

Object reference not set to an instance of an object in Session

I am getting an error in this line of code Session.Linq<Employees>() :
" An object reference is required for non-static field,method, or property 'System.Web.UI.Page.Session.get'.
This is my code :
public static object GetData(Dictionary<string, object> tableParams)
{
IQueryable<Employees> Employee = Session.Linq<Employees>();
if (tableParams.ContainsKey("sEcho"))
{
var parser = new DataTableParser<Employees>(tableParams, Employee);
return parser.Parse();
}
return Employee;
}
If I use HttpContext.Current.Session.Linq<Employees>();
then i get:
'System.Web.SessionState.HttpSessionState' does not contain a definition for 'Linq' and no extension method 'Linq' accepting a first argument of type 'System.Web.SessionState.HttpSessionState' could be found '
What do i need to do to get this to work? Am I missing a namespace for Linq with regard to Session?I am using System.Linq and System.Linq.Expression.
I think you're misunderstanding something. What you're trying to do doesn't have anything to do with Linq, at least not in the context of retrieving the object from session.
You need to retrieve the object from session and unbox it:
var list = Session["MyList"] as List<int>;
if (list != null)
{
//the list was found and you can start using it here
}

Resources