public static LoginResult CreateLoginSuccessResponse(this PortalIdentity user)
{
return new LoginResult(
true,
string.Empty,
user.Roles,
false
);
}
public class PortalIdentity : IdentityUser
{
public string Firstname { get; set; }
public string Lastname { get; set; }
}
This block of code is for creating a success response whenever a user logs in successfully. I am a QA and trying to learn how to write unit tests. I am not sure how to write unit test for "this" keyword
this (in the above context at least) just means it is an extension method.
To test it, new up a PortalIdentity, assign to a variable (bob) and call bob.CreateLoginSuccessResponse():
var bob = new PortalIdentity(you may need parameters here);
var result = bob.CreateLoginSuccessResponse();
If the call to bob.CreateLoginSuccessResponse() doesn't compile, then the extension method is likely in a different namespace. As per the docs, you need to:
In the calling code, add a using directive to specify the namespace
that contains the extension method class.
Related
public class Details
{
public int Id { get; internal set; }
public string Name { get; set; }
}
I have a task where a setter in a model has an internal attribute and I have tried adding stuff like
[assembly: InternalsVisibleTo("sometestrepo")]
over the model class but to no avail. I googled for a couple of hours and I can't seem to find an answer. Is it even possible to xunit test it or mock and object so that it would allow to create an object with an Id. Otherwise how else am I supposed to fully test CRUD methods that are all based around ID parameter?
The solution is to make private members that you want to test internal.
then you can add InternalsVisibleTo attribute.
[assembly: InternalsVisibleTo("sometestrepo")]
if you're using Moq,You can use something like that:-
var mockAddress = new Mock<Details>();
mockAddress.SetupGet(p => p.Id).Returns(42);
mockAddress.SetupGet(p => p.Name).Returns("Whatever you want to match");
var mockAddressRepository = new Mock<IRepository<Details>>();
var addresses = new List<Details> { mockAddress.Object };
mockAddressRepository.Setup(p => p.GetEnumerator()).Returns(addresses.GetEnumerator());
var addressToMatch = mockAddressRepository.Object.FirstOrDefault(address => address.Id == 42);
Console.WriteLine(addressToMatch.Name);
Expected Output Is:-
Whatever you want to match
One solution that might work is to use a fake.
In your Test class create a fake Details class, inheriting from Details. Then you could new up the property.
public class FakeDetails : Details
{
public new int Id { get; set; }
}
You could use the fake in your test then to set the properties.
var fakeDetails = new FakeDetails();
fakeDetails.Id = 15;
fakeDetails.Name = "Some Name";
I'm attempting to use HangFire to schedule any class that implements a certain interface I have called IScheduledService. These services run as expected, but HangFire UI always shows the same name for each service in the HangFire dashboard PerformService(). I know this is by design because I'm passing the same function name into each job, but users don't really know what specific job is running.
I created the interface with ServiceName because I thought may be able to pass that into HangFire to override the visible job name instead of the name of the function being called, but don't see the ability to modify the job name. Is there a way to provide a custom job name so that the HangFire UI will show the title of each job based on the value of ServiceName property?
public interface IScheduledService
{
string ServiceId { get; }
string ServiceName { get; }
void PerformService();
}
public class Service1 : IScheduledService
{
public string ServiceId { get => "e56643b1-f0cf-44b2-81ef-bf7a085de760"; }
public string ServiceName { get => this.GetType().Name; }
public void PerformService()
{
Console.WriteLine($"Hello world from {ServiceName}");
}
}
You can display multiple arguments. In my implementation, I have DisplayName instead of JobDisplayName (Hangfire ver 1.7.5)
public static class Func
{
[DisplayName("JobID: {0} => [{1}:{2}]")]
public static void Execute(long requestID, string stepName, string stepLocation)
{
// do work here
}
}
// above method is called by the background.enqueue call
BackgroundJob.Enqueue(() => Func.Execute(longId, stepName, stepLocation);
That seems to provide the information relevant to the job that is executed.
Try using JobDisplayNameAttribute.
I see a couple spots in the code where it might be rendered...
In the RecurringJobsPage and the JobDetailsPage you can see it calling HtmlHelper.JobName
HtmlHelper has some code looking for JobDisplayNameAttribute
https://github.com/HangfireIO/Hangfire/blob/a07ad0b9926923db75747d92796c5a9db39c1a87/src/Hangfire.Core/Dashboard/HtmlHelper.cs
You can see reference to it in an issue that was closed to Release 1.7.0. If you are on that version.
https://github.com/HangfireIO/Hangfire/issues/1136
Also there are some references in old Issues to using DisplayNameAttribute on the method.
Try decorating the method with either JobDisplayName or DisplayName like this
[JobDisplayName("RunJobNumberOne")]
public void RunSomeJob(string arg){
Should I use static in the following 2 cases:
Case 1)
public class RequestHeader
{
private string Username { get; set; }
private string Password { get; set; }
private string AccessKey { get; set; }
public string url { get; set; }
public string pageid { get; set; }
public string organizationid { get; set; }
private RequestHeader()
{
}
public static RequestHeader GetRequestHeader(string url, string pageid, string organizationid)
{
return new RequestHeader()
{
Username = "Some logic to fetch username",
Password = "Some logic to fetch password",
AccessKey = "Some access key",
url = url,
pageid = pageid,
organizationid = organizationid,
};
}
}
Case 2)
public class HttpClientHelper
{
public static HttpClient GetHttpClient(RequestHeader header)
{
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
foreach (var property in header.GetType().GetProperties())
{
client.DefaultRequestHeaders.Add(property.Name, property.GetValue(header).ToString());
}
return client;
}
}
I know that static is not used where state is maintained. I believe I am not maintaining any state here. I will be using this in a class library and I will be using these for calling a rest service.
The only thing which makes me want to use static here is not to initialize these class.(I know this is a very baaad reason).
Please let me know your thoughts. Is there something which I am not seeing in this.
Note: 1) I am aware of the small casing for some of the properties. It is in sync with the rest service on which I have absolutely no control.
2) If I have multiple RequestHeader in future, I might create an IRequestHeader which has a method GetRequestHeader. So the different RequestHeaders will implement this. In this case I know I cant keep a static method in interface.
Please Keep these 2 conditions away and let me know your thoughts.
What you have here seems to be a version of the Static Factory Pattern. This is a well-known pattern and is perfectly fine to use.
You might also be interested in the non-static version of the Factory Pattern.
I assume HttpClient is not "your class", in which case you of course can't add a method inside the class itself.
The only thing which makes me want to use static here is not to initialize these class.(I know this is a very baaad reason).
Technically you're instantiating and initializing these classes no matter how you do it (factory method or no factory method), the only question is if you are going to use a factory method to do the instantiation and initialization for you.
If you have to use same values for each call you should use static fields, because static fields are used when only one copy of the variable is required. The same static field will share the copy across all the instances.
I have a class called "Account".
Here are my codes:
// Account.cs
public partial class Account
{
private Account.Credential _credential = new Account.Credential();
public void Login(string UserID, string UserPW)
{
try
{
// do something
_credential.CookieCollection = browser.CookieCollection;
_credential.CookieContainer = browser.CookieContainer;
_credential.UserID = "test";
_credential.UserPW = "test";
}
catch (Exception err)
{
throw err;
}
}
}
// Credential.cs
public partial class Account
{
public class Credential
{
// Model
public CookieCollection CookieCollection { get; set; }
public CookieContainer CookieContainer { get; set; }
public string UserID { get; set; }
public string UserPW { get; set; }
}
}
// Form1.cs
public void ABC()
{
Account[] _account = new Account[2];
_account[0].Login("myID", "myPW");
Account.Credential _cred = _account[0].Credential; ---> I get an error.
}
But when I write a mothod call the Account class in array and call the sub class which is Credential, it gives me an error.
'Credential': cannot reference a type through an expression; try 'Account.Credential' instead.
Because, Login method is in Account Class I should have make an array of Account class. Not Credential class.
Does anyone know how to fix this?
As the error is trying to tell you, the Credential type is a part of the Account type; not any single Account instance.
It makes no sense to refer to the type myAccounts[42].Credential or mikesAccount.Credential.
If you want to get that user's credential, you'll need to refer to a field or property of the Account class.
You could write myAccounts[42]._credential, except that _credential is private, so that will give a different error.
You should make a public, probably-read-only, property.
This is happening because Account.Credential is an internal type to Account and isn't used like how you're using it. What code is attempting to do would be similar to trying
var str = String;
You need to initialize an Account.Credential. A simple was is to use new inside Account's ctor or the Login() method.
I noticed you're going to run into further problems with your code - if you want to access the Account.Credential reference declared inside Account, you'll need to expose it through a method or change the access modifier.
I have a class with a method that returns an object of type User
public class CustomMembershipProvider : MembershipProvider
{
public virtual User GetUser(string username, string password, string email, bool isApproved)
{
return new User()
{
Name = username
,Password = EncodePassword(password)
,Email = email
,Status = (isApproved ? UsuarioStatusEnum.Ativo : UsuarioStatusEnum.ConfirmacaoPendente)
// ...
};
}
// ..
}
User is a domain object. Note the Id property with setter as protected:
public class User : IAuditable, IUser
{
public virtual int Id { get; protected set; }
public virtual string Name { get; set; }
public virtual string Email { get; set; }
public virtual UsuarioStatusEnum Status { get; set; }
public virtual string Password { get; set; }
}
Id is protected because it is generated by the database.
Test project
In my Test project I have a Fake repository with a method Store to save/update the object:
public void Store(T obj)
{
if (obj.Id > 0)
_context[obj.Id] = obj;
else
{
var generateId = _context.Values.Any() ? _context.Values.Max(p => p.Id) + 1 : 1;
var stubUser = Mock.Get<T>(obj); // In test, will always mock
stubUser.Setup(s => s.Id).Returns(generateId);
_context.Add(generateId, stubUser.Object);
}
}
In CustomMembershipProvider I have public override MembershipUser CreateUser method that calls the GetUser to create a User.
This way, all I have to do is mock the GetUser method so that the repository can generate the Id
var membershipMoq = new Mock<CustomMembershipProvider>();
membershipMoq.CallBase = true;
membershipMoq
.Setup(p => p.GetUser(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<bool>()))
.Returns<string, string, string, bool>( (username, password, email, isAproved) => {
var moqUser = new Mock<User>();
moqUser.Object.Name = username;
moqUser.Object.Password = password;
moqUser.Object.Email = email;
moqUser.Object.Status = (isAproved ? UsuarioStatusEnum.Ativo : UsuarioStatusEnum.ConfirmacaoPendente);
return moqUser.Object;
});
_membershipProvider = membershipMoq.Object;
Problem
In theory everything is correct. When CreateUser call 'GetUser' to create a user, the user will return Mock filled;
[TestMethod]
public void CreateUser_deve_criar_usuario_no_repositorio()
{
// Act
MembershipCreateStatus status;
var usr = _membershipProvider.CreateUser(
_fixture.Create<string>(),
_fixture.Create<string>(),
_fixture.Create<string>(),
null, null, true, null,
out status);
// usr should have name, email password filled. But not!
// Assert
status.Should().Be(MembershipCreateStatus.Success);
}
The problem is that Email, Name, Password are empty (with default values)!
The way you prepare the mocked user is the problem.
moqUser.Object.Name = username;
will not set the name, unless you have setup the mock properly.
Try this before assigning values to properties:
moqUser.SetupAllProperties();
This method will prepare all properties on the mock to be able to record the assigned value, and replay it later (i.e. to act as real property).
You can also use SetupProperty() method to set up individual properties to be able to record the passed in value.
Another approach is:
var mockUser = Mock.Of<User>( m =>
m.Name == "whatever" &&
m.Email == "someone#example.com");
return mockUser;
I think you are missing purpose of mocking. Mocks used to mock dependencies of class you are testing:
System under test (SUT) should be tested in isolation (i.e. separate from other units). Otherwise errors in dependencies will cause your SUTs tests to fail. Also you should not write tests for mocks. That gives you nothing, because mocks are not production code. Mocks are not executed in your application.
So, you should mock CustomMembershipProvider only if you are testing some unit, which depends on it (BTW it's better to create some abstraction like interface ICustomMembershipProvider to depend on).
Or, if you are writing tests for CustomMembershipProvider class, then it should not be mocked - only dependencies of this provider should be mocked.
Specifies that the all properties on the mock should have "property behavior",
meaning that setting their value will cause them to be saved and later returned when the properties is requested.
(This is also known as "stubbing".)
The default value for each property will be the one generated as specified by the
property for the mock.
mock.SetupAllProperties();