I'm new to Unit Testing and I'm using Rhino Mock in ASP.NET MVC
I have created a main test class with this code :
[TestFixture]
public class PersistenceTest
{
[Test]
protected T SaveAndLoadEntity<T>(T entity) where T : BaseEntity
{
var mockDataSource = MockRepository.GenerateMock<IRepository<T>>();
mockDataSource.Add(entity);
var fromDb = mockDataSource.FindBy(entity.Id);
return fromDb;
}
}
and create a customer test class like this :
[TestFixture]
public class CustomerTests : PersistenceTest
{
[Test]
public void Can_Save_And_Load_Customer()
{
var customer = new Customer()
{
Id = 12,
Name = "Reza",
Family = "Pazooki",
Company = "Rozaneh",
Email = "ipazooki#gmail.com",
Mobile = "09352463668",
Fax = "021-44869059",
Tel = "021-44869059",
WebSite = "www.rozanehmedia.com"
};
var fromDb = SaveAndLoadEntity(customer);
fromDb.ShouldNotBeNull();
}
}
but when run the code, it says that return value from Database is NULL!!!
I don't know what is wrong with my code but I save and retrieve data from mock repository and it seems every thing is ok.
tnx form any help in forward :)
Mocks are used to record invocations on objects for further verification or to provide values when called (later behavior requires setup).
In your SaveAndLoadEntity method you make calls to mock (Add and FindBy). Since mock is a fake object with no real behavior, those calls do nothing (they don't save nor extract any entities to/from database).
If you want to test persistence layer you should be doing tests against real database instance (or optionally, in-memory one).
// [Test] attribute is not needed
protected T SaveAndLoadEntity<T>(T entity) where T : BaseEntity
{
var dataSource = new DataSource("connection string");
dataSource.Add(entity);
var fromDb = dataSource.FindBy(entity.Id);
return fromDb;
}
At the moment you are making calls to not-setup mock which doesn't achieve anything.
Thank you jimmy_keen.
I change my code according to your advice like this and it worked great :)
[TestFixture]
public class PersistenceTest
{
protected ISession Session;
protected ITransaction Transaction;
[SetUp]
public void SetUp()
{
var helper = new NHibernateHelper("...connectionString....");
Session = helper.SessionFactory.OpenSession();
Transaction = Session.BeginTransaction();
}
protected T SaveAndLoadEntity<T>(T entity) where T : BaseEntity
{
Session.Save(entity);
Transaction.Commit();
var fromDb = Session.Get<T>(entity.Id);
return fromDb;
}
}
Related
I am working on an ASP.Net Core MVC Web application.
My Solution contains 2 projects:
One for the application and
A second project, dedicated to unit tests (XUnit).
I have added a reference to the application project in the Tests project.
What I want to do now is to write a class in the XUnit Tests project which will communicate with the database through entity framework.
What I was doing in my application project was to access to my DbContext class through constructor dependency injection.
But I cannot do this in my tests project, because I have no Startup.cs file. In this file I can declare which services will be available.
So what can I do to get a reference to an instance of my DbContext in the test class?
You can implement your own service provider to resolve DbContext.
public class DbFixture
{
public DbFixture()
{
var serviceCollection = new ServiceCollection();
serviceCollection
.AddDbContext<SomeContext>(options => options.UseSqlServer("connection string"),
ServiceLifetime.Transient);
ServiceProvider = serviceCollection.BuildServiceProvider();
}
public ServiceProvider ServiceProvider { get; private set; }
}
public class UnitTest1 : IClassFixture<DbFixture>
{
private ServiceProvider _serviceProvider;
public UnitTest1(DbFixture fixture)
{
_serviceProvider = fixture.ServiceProvider;
}
[Fact]
public void Test1()
{
using (var context = _serviceProvider.GetService<SomeContext>())
{
}
}
}
But bear in your mind using EF inside a unit test is not a good idea and it's better to mock DbContext.
The Anatomy of Good Unit Testing
You can use Xunit.DependencyInjection
For unit tests you need to mock your context.
There is a great nuget package for mocking that is called Moq.
Some help to get you started:
public ClassName : IDisposable
{
private SomeClassRepository _repository;
private Mock<DbSet<SomeClass>> _mockSomeClass;
public ClassName()
{
_mockSomeClass = new Mock<DbSet<SomeClass>>();
var mockContext = new Mock<IApplicationDbContext>();
mockContext.SetupGet(c => c.SomeClass).Returns(_mockSomeClass.Object);
_repository = new SomeClassRepository(mockContext.Object);
}
public void Dispose()
{
// Anything you need to dispose
}
[Fact]
public void SomeClassTest()
{
var someClass = new SomeClass() { // Initilize object };
_mockSomeClass.SetSource(new[] { someClass });
var result = _repository.GetSomethingFromRepo( ... );
// Assert the result
}
}
For integration tests you do the same thing but the setup is:
_context = new ApplicationDbContext();
Make sure that your TestClass inherits from IDisposable (TestClass : IDisposable) so that you can dispose the context after each test.
https://xunit.github.io/docs/shared-context
You can to use package Microsoft.EntityFrameworkCore.InMemory
var _dbContextOptions = new DbContextOptionsBuilder<DbContext>().UseInMemoryDatabase(Guid.NewGuid().ToString()).Options;
And then
var context = new DbContext(_dbContextOptions);
I have a dotnet 3.1 core web api application and looking to use xUnit. In this, I am only wanting to test the public methods, BUT I do have several private methods that either make a call to a database to return data or make a rest call to an external service.
Question:
I am NOT trying to test the private method, but how can I fake the return data of the private methods, so that when my public method calls the private method, I can return a fake set of data so that my public method and calculations can be tested?
Thanks in advance!
Update
Here is an example of what I am trying to do.
public class FooRepository{
public MyObject CalculateValues{
var myReturnObject = new MyObject();
var crewSalaries = GetCrewSalaries(myCrew)
myObject.TotalSalary = crewSalaries.Sum(x=>x.salary)
// Insert other calculations here
}
private MyObject GetCrewSalaries(List<Crew> myCrew){
return dbContext.Where(x=>x.id == myCrew.id).ToList();
}
}
Public Class FooRepositoryTest{
[Fact]
public Test1()
{
var fooClass = new fooClass();
// mock or hijack fooClass.GetCrewSalaries, so that I can return fake data
var result = fooClass.CalculateValues();
// assert statement here
}
private GetFakeSalaryData()
{
return new List<CrewSalaries>{
[
id:1,
salary:23
],
[
id:2,
salary:23.1
],
}
}
}
I need to retrieve data from the db, via a service, in order to test captured data for structural validity.
i.e. The db data specifies the sizes of parts of a captured concatenated string, (in a certain order), which I mock. So no worries there.
But I don't want to mock the service's data.
I want to actually retrieve the db data, which can change/vary vastly for different clients, and different scenarios, or be changed regularly.
So, changing the mocked data for each scenario is not feasible.
The Service implements an interface and also injects the Data Access Layer's interface.
I do set 'CallBase' as true, but I'm not getting db Data back.
Please help.
Thanks
public interface I_PartDao
{
ExBool List(out List<GXL_PartSizes> _PartSizes);
}
public class GXL_PartSizes
{
public int? ID { get; set; }
public int? PartLength { get; set; }
public int? SortOrder { get; set; }
public GXL_PartSizes()
{
this.ID = null;
this.PartLength = null;
this.SortOrder = null;
}
}
// Service Layer
public interface I_PartBo
{
ExBool List(out List<GXL_PartSizes> _PartSizes);
}
public class PartBo : I_PartBo
{
// For the injection of the Dao services (Dao handles the Ado CRUD operations against MSSQL dbase)
private I_PartDao PartDao;
public PartBo(I_PartDao dao_Part)
{
this.PartDao = dao_Part ?? throw new ArgumentNullException("dao_Part");
}
public ExBool List(out List<GXL_PartSizes> _PartSizes)
{
return this.PartDao.List(out _PartSizes);
}
}
[TestClass]
public class GXL_ConcatenatedStructures_Test
{
ExBool result = new ExBool(); // A class to handle error messages and statuses
private List<GXL_PartSizes> partSizes;
[TestMethod]
public void Test_Part_1_Length_matches_dbStructure_for_part1()
{
// Arrange
var mockService = new Mock<I_PartBo>();
// This is retrieved from the data posted back to the controller,..but for here and now, just a local populated strign var
var concatenatedString_part1 = "ABC";
// Act
//mockService.CallBase = true;
mockService
.Setup(x => x.List(out partSizes))
.Returns(result);
// Assert
Assert.AreEqual(concatenatedString_part1, partSizes[0].PartLength);
}
}
I thought that there was a way to do what I wanted to, by using moq.
However,
by just using the normal concrete classes, as per the usual (sans DI) way, The db data is retrieved.
i.e.
NamespaceX.GLX_SetupDao dao = new NamespaceX.GLXSetupDao("data source=LAPTOP-a; Initial
Catalog=aaaa; Integrated Security=True;");
GLX_SetupBo boService = new GLX_SetupBo(dao);
result = boService.List(out List<GXL_PartSizes> sizes);
I Would like to test my Hub in SignalR, what is the best approach?
Possible solutions I have thought about so far:
Create a testable Hub
Abstract logic to separate class
Selenium (would like to test smaller units)
Or is it some SignalR testing features have overlooked
Currently using SignalR 0.4, and NUnit as the testing framework.
This link shows how to unit test SignalR hub methods using Moq. You mock up the respository, clients, context, and the caller. Here's the code from the site, I made some minor changes to make it work with the latest SignalR:
public class TestableChatHub : ChatHub
{
public Mock<IChatRepository> MockChatRepository { get; private set; }
public TestableChatHub(Mock<IChatRepository> mockChatRepository)
: base(mockChatRepository.Object)
{
const string connectionId = "1234";
const string hubName = "Chat";
var mockConnection = new Mock<IConnection>();
var mockUser = new Mock<IPrincipal>();
var mockCookies = new Mock<IRequestCookieCollection>();
var mockRequest = new Mock<IRequest>();
mockRequest.Setup(r => r.User).Returns(mockUser.Object);
mockRequest.Setup(r => r.Cookies).Returns(mockCookies.Object);
Clients = new ClientProxy(mockConnection.Object, hubName);
Context = new HubCallerContext(mockRequest.Object, connectionId);
var trackingDictionary = new TrackingDictionary();
Caller = new StatefulSignalProxy(
mockConnection.Object, connectionId, hubName, trackingDictionary);
}
}
Then the site shows that you can use this testable hub to write unit tests:
[TestClass]
public class ChatHubTests
{
private TestableChatHub _hub;
public void SetUpTests()
{
_hub = GetTestableChatHub();
}
[Test]
public void ExampleTest()
{
SetUpTests();
const string message = "test";
const string connectionId = "1234";
var result = _hub.Send(message);
_hub.MockChatRepository.Verify(r => r.SaveMessage(message, connectionId));
Assert.IsTrue(result);
}
private TestableChatHub GetTestableChatHub()
{
var mockRepository = new Mock<IChatRepository>();
mockRepository.Setup(m => m.SaveMessage(
It.IsAny<string>(), It.IsAny<string())).Returns(true);
return new TestableChatHub(mockRepository);
}
}
It's quite simple to create to unit test SignalR hubs using a couple of neat tricks. One thing to note is that SignalR uses dynamic classes which might not be supported by your mocking framework (I use NSubstitute).
public class ProjectsHub: Hub
{
public void AddProject(string id)
{
Clients.All.AddProject(id);
}
}
[TestFixture]
public class ProjectsHubTests
{
// Operations that clients might receive
// This interface is in place in order to mock the
// dynamic object used in SignalR
public interface ISignals
{
void AddProject(string id);
}
[Test]
public void AddProject_Broadcasts()
{
// Arrange
ProjectsHub hub = new ProjectsHub();
IHubCallerConnectionContext clients =
Substitute.For<IHubCallerConnectionContext>();
ISignals signals = Substitute.For<ISignals>();
SubstituteExtensions.Returns(clients.All, signals);
hub.Clients = clients;
// Act
hub.AddProject("id");
// Assert
signals.Received(1).AddProject("id");
}
}
Rewriting this to use e.g. Moq should be pretty simple.
This question is from a while ago, but I'll do my best to answer anyway.
If you have a lot of logic in your actual hub class, it would certainly make sense to abstract the logic to a separate class. I did the same for my SignalR-powered multiplayer demo. The only behaviour that should go in your hub class itself is the one related to messaging. All further action should be delegated.
Note: This is very much like the guidelines for controller design in ASP .NET MVC: Keep your controllers small and delegate the real work.
If you want integration tests with SignalR actually doing some work, selenium webdriver would be a good option. But you will probably need to do some tweaking to get the SignalR messaging working perfectly in the context of the tests. Do a google search for "signalr selenium" (without the quotes) to get started on the right track.
Some blogposts about automated tests for SignalR => here and here
With the SignalR 2.0 you can do it this way:
// Arrange
var hub = new CodeInteractivePreviewHub();
var mockClients = new Mock<IHubCallerConnectionContext<dynamic>>();
hub.Clients = mockClients.Object;
dynamic all = new ExpandoObject();
mockClients.Setup(m => m.All).Returns((ExpandoObject)all);
// Act
var allSourceCodes = hub.InitiateCommunication(); //Change this line to your Hub's method
// Assert
Assert.IsNotNull(allSourceCodes);
This is modified version of Iarsm's answer, to work with XUnit and MOQ.
using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;
using Moq;
using Xunit;
namespace TestLibrary {
public class ProjectsHub : Hub {
public void AddProject(string id) {
Clients.All.AddProject(id);
}
}
public class ProjectsHubTests {
// Operations that clients might receive
// This interface is in place in order to mock the
// dynamic object used in SignalR
public interface ISignals {
void AddProject(string id);
}
[Fact]
public void AddProject_Broadcasts() {
// Arrange
ProjectsHub hub = new ProjectsHub();
var clients = new Mock<IHubCallerConnectionContext<dynamic>>();
var signals = new Mock<ISignals>();
hub.Clients = clients.Object;
signals.Setup(m => m.AddProject(It.Is<string>(s => s == "id"))).Verifiable();
clients.Setup(m => m.All).Returns(signals.Object);
// Act
hub.AddProject("id");
// Assert
signals.VerifyAll();
}
}
}
My interface was out of the test project, but here's how I did it using NUnit and Moq.
using Microsoft.AspNetCore.SignalR;
using Moq;
using NUnit.Framework;
namespace TestLibrary
{
// Operations that clients might receive
// This interface is in place in order to mock the
// dynamic object used in SignalR
public interface ISignals
{
void AddProject(string id);
}
public class ProjectsHub : Hub<ISignals>
{
public void AddProject(string id)
{
Clients.All.AddProject(id);
}
}
public class ProjectsHubTests
{
[Test]
public void AddProject_Broadcasts()
{
// Arrange
ProjectsHub hub = new ProjectsHub();
var clients = new Mock<IHubCallerClients<ISignals>>();
var signals = new Mock<ISignals>();
hub.Clients = clients.Object;
signals.Setup(m => m.AddProject(It.Is<string>(s => s == "id"))).Verifiable();
clients.Setup(m => m.All).Returns(signals.Object);
// Act
hub.AddProject("id");
// Assert
signals.VerifyAll();
}
}
}
How do I create unit test with context based on integration component?
I have identified problem as the Extension is trying to resolve implementation and returning error message:
"Object reference not set to an instance of an object."
My class:
public sealed class GetListOfServiceIdsToProcess
{
public InOutArgument<IArguments> Arguments { get; set; }
protected override void Execute(CodeActivityContext context)
{
// I am recieving my error exception here
context.GetExtension<lib.Extension.MyExtenstion>();
var targetIds= (List<int>)Settings.Get("targetIds");
var wfa = this.Arguments.Get(context);
wfa.ListTargetIds = targetIds;
Arguments.Set(context, wfa);
}
}
My Test so far:
I have problem with implementation of the test as far i could get it:
/// <summary>
///A test for Execute
///</summary>
[TestMethod()]
public void ExecuteTest()
{
// create Isettings mock to return collection of service ids
var expected = new List<int>() { 30, 20 };
var wfaInput = new TestWorkFlow();
var serviceIdList = new GetListOfServiceIdsToProcess();
var wfParam = new Dictionary<string, object>();
wfParam.Add("WorkFlowArguments", wfaInput);
var results = WorkflowInvoker.Invoke(serviceIdList, wfParam);
var wfaResult = (IWorkFlowArguments)results["WorkFlowArguments"];
Assert.AreEqual(expected, wfaResult.ListOfServiceIdsToProcess);
}
Instead of using the static WorkflowInvoker.Invoke() new up a WorkflowInvoker instance and add a mock, or whatever is needed for your test, lib.Extension.MyExtenstion to the Extensions collection.
[TestMethod]
public void ExecuteTest()
{
// ...
var invoker = new WorkflowInvoker(activityToTest);
// This way your extension will be available during execution
invoker.Extensions.Add(new MyExtension());
var results = invoker.Invoke(inputArgs);
// ....
}
I have run through multiple options and the problem what I have is MS Workflow.
I have extracted all logic away from workflow code activity into separate class and this class has been put under tests.
This is the best I could do for this. As I have base classes, that are injected, but I could not easily implement what I needed.
Thank you all for help anyway.