How to mock a Class with IEnumerable - c#

I am using Moq for unit testing in C# and want to put some fake data in the following class.
public class UserResponse
{
public IEnumerable<usertab> userlist{get;set;}
public string Name {get;set;}
public string state {get;set;}
public string country {get;set}
}
public class usertab
{
public string tname {get;set;}
public string fname {get;set;}
}
Please correct me if below code is correct to fake a class wtih IEnumerable
var userdata = new usertab[]{
new usertab{tName="Employee",fName="abc"},
new usertab{tName="Employee",fName="xyz"},
};

Well you're not "faking" it at all - you're just using an array as the implementation. There's nothing wrong with doing that - personally I like using real code within tests, so long as:
You have confidence in the other code you're relying on (arrays in this case) either because it's supplied from a trustworthy source (the BCL in this case) or you have tests
You don't need to perform interaction testing - for example, if you want to check that you only iterate over the collection once, arrays won't help you do that
The real code doesn't slow down the testing (e.g. by making network connections, requiring a database etc). Not a problem with arrays.

Related

Assigning Dynamic Variables from an Input Model C#

I am having some issues understanding how I can assign dynamic values from another class into other variables - I have tried using the correct namespaces, correct syntax and reading up on the documentation that the error provides - however no luck even when trying to implement examples shown. I have very little knowledge in regards to C# as I am mainly doing front end, however have to step up and start picking up some Back end oriented things at the company I work at
The current code I have is as follows:
BrazeConnectionInputs.cs
namespace Workflow.Connector.Braze.Models
{
public class BrazeConnectionInputs
{
public string Username { get; set; }
public string Password { get; set; }
}
}
CreateCampaign.cs
public class CreateCampaignRunner
{
private const string Username = BrazeConnectionInputs.Username; // BrazeConnectionInputs.Username errors
private const string Password = BrazeConnectionInputs.Password; // BrazeConnectionInputs.Username errors
}
You need to learn about objects vs classes. You should have an instance of the source class (BrazeConnectionInputs) that might be called something like model.
You can then explicitly assign across by creating a new instance of CreateCampaignRunner like var runner = new CreateCampaignRunner() and then assign the values in a number of ways:
Explicitly like runner.UserName = model.UserName
By using an explicit constructor var runner = new CreateCampaignRunner(model)
Object initializer syntax
Other ways are available
Highly recommend you do a basic C# course

Mocking a method to assign value to field in Model C# Moq

I need to add a method to a model that given some parameters assigns a value to one of the model's fields.
public class ModelName: SomeModel<ModelName>, IModelName
{
[Field]
public string SomeField{ get; set; }
[Field]
public string FieldSetByMethod{ get; set; }
public new async Task MethodToSetField(string parameter)
{
var someClassInstance = new SomeExternalClass(parameter);
FieldSetByMethod = someClassInstance(parameter).method();
}
}
Now when I'm writing unit tests and I want to have a way of checking that this MethodToSetField was called. However, I can't really actually call the MethodToSetField method as creating SomeExternalClass is not desirable (e.g. because it creates unique ID).
I don't really have experience with neither C# nor Moq. How can I mock this function so it behaves more or less like this:
ModelNameInstance.Setup(c => c.MethodToSetField("Parameter")).Assigns(FieldSetByMethod,"DummyValue");
Or maybe I can somehow restructure the code / write tests in a way to imitate this behavior?
You could inject ISomeExternalClass into this class and then mock it, and test against the mock, or if you can't do that - inject ISomeExternalClassFactory into this class and then mock it. ISomeExternalClassFactory mock would return a mock of ISomeExternalClass that you could setup and test against.

Is there a way to make FluentValidation more dynamic?

We just received a phase 1 release from a vendor to translate an archaic PowerBuilder application into C# MVC with Angular 5 (we have an Angular guy that has already mostly rewritten the front end in 7 so the security concerns from 5 are a nonissue). Since the statement of work only required them to reproduce the application there are next to zero validations on input because there wasn't much, if any, on the original application.
I have recently done some research into FluentValidation and like it for its reusability later in applications that will use the same overall data. However, looking at this code the models in the MVC are not normalized like they probably should be and so we have dozens of models that likely could be normalized out so that there would be less overlap in data fields such as First Name, Last Name, Address, Business Address etc.
I have basic experience with generics and reflection and have supported a few more advanced examples in the past. So I was trying to find some way to utilze these two concepts to make the validators more dynamic.
I was unable to find much in the way of more advanced FluentValidation examples other than the basic hard connection to a given named model. I have tried to use the generic T in place of the model but was unable to bridge the gap and access the object being passed into the validation.
public class FormValidator : AbstractValidator<ModelExample>
{
public FormValidation()
{
}
}
//tried to do something like this but wasn't able to access the .HasProperties. Although I was able to access the GetProperties,
//having trouble implementing it into the RuleFor however.
public class FormValidation<T> : AbstractValidator<T>
{
RuleFor(x => x.GetType().GetProperty(nameof({something if it exists}).{check stuff is valid}
{
public class ModelExample
{
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateOfBirth { get; set; }
}
public class OtherModelExample
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
My end goal would be to be able to pass related objects into a given validator and it would be able to determine if the properties existed and act accordingly.
This may be an issue where I don't really know how to ask the question in Google, I tend to have issue wording things in a way where it brings up what I would expect.
This also may not even be possible but if it could save me from writing a series of hard coupled validators that I might have to rewrite later if we ever are allowed to normalize the data flow it would be of great help.
Any articles or documentation with more advanced examples than the simple ones I find would be of great use even beyond this project. Most of the tutorials I find are very basic examples and I sometimes have a hard time picturing them in "real" code application.
Thanks
Instead of creating generic validators for a whole model, have you considered the reverse and creating them for each property?
If you use custom property validators you can specify the validator logic once, and then simply create a validator class per view model.
eg:
class Program
{
static void Main(string[] args)
{
var person = new Person
{
Name = "Ada",
NickName = "A"
};
var validator = new PersonValidator();
var result = validator.Validate(person);
//Should be a problem with the NickName
}
}
class Person
{
public string Name { get; set; }
public string NickName { get; set; }
}
class PersonValidator : AbstractValidator<Person>
{
public PersonValidator()
{
RuleFor(x => x.Name).SetValidator(new NameValidator());
RuleFor(x => x.NickName).SetValidator(new NameValidator());
}
}
public class NameValidator : AbstractValidator<string>
{
public NameValidator()
{
RuleFor(x => x).Must(x => x.Length > 1)
.WithMessage("The name is not long enough");
}
}
This is probably a safer option too, as it's opt in rather than implicit.

MongoDb C# failed to serialize the response

Class (Entity)
public class Entity
{
public ObjectId Id { get; set; }
public Entity()
{
Id = ObjectId.GenerateNewId();
}
}
Class (Member)
public class Member : Entity
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public string MobileNumber { get; set; }
}
Action
public dynamic Get()
{
var response = UnitOfWork.MemberRepository.GetMembers();
return response;
}
I'm building a API using .NET WebAPI and using mongodb as a datastore, I'm have some troubles serializing the responding object from the database.
Can't understand why, search the internet a while and found similar problems with no solutions. Either I'm a bad google searcher or there answer is hidden somewhere deep:)
Full stack trace: http://pastie.org/8389787
This is little guessing, but the code really isn't too telling.
I'm pretty sure this is because the C# Mongo driver's BsonDocument exposes a ton of properties like AsBoolean, AsInt, AsString, etc. Calling those getters on data that isn't convertible to the respective type causes an exception. While I don't see them in the stack trace, that might be a compiler optimization.
One solution is to make the code strongly-typed (if it isn't already). I don't know what UnitOfWork.MemberRepository.GetMembers(); is, but it hides what you're doing and it's also not clear what it returns. You're losing a lot of the advantages of the C# driver. The Collection<T> class is pretty much a repository pattern already by the way.
A cleaner approach (they aren't mutually exclusive) is to not serialize the database object to the outside world, but use DTO for the WebAPI side and translate between them, for instance using AutoMapper. I would always do this, because you're throwing an object that might be decorated with DB-Attributes in a serializer you don't know - that could lead to all sorts of problems. Also, you often want to hide certain information from the outside, or make it read-only.
Another option is to use ServiceStack.Text as a JSON-serializer instead, which tends to cause less trouble in my experience.

Unit testing a method with Moq

I'm trying to learn how to do Unit testing with C# and Moq, and I've built a little test situation. Given this code:
public interface IUser
{
int CalculateAge();
DateTime DateOfBirth { get; set; }
string Name { get; set; }
}
public class User : IUser
{
public DateTime DateOfBirth { get; set; }
string Name { get; set; }
public int CalculateAge()
{
return DateTime.Now.Year - DateOfBirth.Year;
}
}
I want to test the method CalculateAge(). To do this, I thought I should try giving a default value to the DateOfBirth property by doing this in my test method:
var userMock = new Mock<IUser>();
userMock.SetupProperty(u => u.DateOfBirth, new DateTime(1990, 3, 25)); //Is this supposed to give a default value for the property DateOfBirth ?
Assert.AreEqual(22, userMock.Object.CalculateAge());
But when It comes to the assertion, the value of CalculateAge() equals 0, although DateOfBirth equals new DateTime(1990, 3, 25).
I know this may look like a silly example, but whatever... I thought I could use mocking to give values to not-yet-developed method/properties in my objects, so the testing of a method wouldn't depend on another component of my class, or even setting up a default context for my object (hence the name of the user here...) Am I approaching this problem the wrong way?
Thanks.
Yes, you approaching it wrong, but don't worry, I'll explain why. First hint would be
you can completely remove your User class and everything will be the
same.
When you are doing:
var userMock = new Mock<IUser>();
You just creating a fake\mock object of that interface, that has nothing to do with your initial User class, so it doesn't have any implementation of CalculateAge method, except of fake one that just silly returns 0. That's why you are getting 0 in your assert statement.
So, you were saying:
thought I could use mocking to give values to not-yet-developed
method/properties in my objects, so the testing of a method wouldn't
depend on another component of my class
You could, let's say you will have some consumer of your IUser, lets say like the following:
class ConsumerOfIUser
{
public int Consume(IUser user)
{
return user.CalculateAge() + 10;
}
}
in that case mocking of IUser will make total sense, since you want to test how your ConsumerOfIUser behaves when IUser.CalculateAge() returns 10. You would do the following:
var userMock = new Mock<IUser>();
userMock.Setup(u => u.CalculateAge()).Returns(10);
var consumer = new ConsumerOfIUser();
var result = consumer.Consume(userMock);
Assert.AreEqual(result, 20); //should be true
It depends on what your trying to test. In this case, you have mocked out the User object, so there is no point in testing anything inside this class as you are replacing it with a mock object. If you want to test the User object then you shouldn't mock it out.
Mocks are used to replace dependant objects that you don't want to test. For example, if you had a Name object instead of a string (e.g contains first name, surname, title etc..) but you didn't want to test the Name object, just the User object, you would create a mock of the Name object to be used when constructing the User object.

Categories

Resources