I'm testing the MbUnit Framework and want to keep my test database in a persistent state after each test. How can I accomplish this?
This is what I'm trying, but my table is filled after the test is completed.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using Gallio.Framework;
using MbUnit.Framework;
using NHibernate;
using NHibernate.Cfg;
namespace BusinessLayer.Tests
{
[TestFixture]
public class PersonNHibernateTests
{
[Test]
[Rollback]
public void CanSavePerson()
{
Configuration config = new Configuration();
config.Configure();
ISessionFactory factory = config.BuildSessionFactory();
using (ISession session = factory.OpenSession())
{
using (ITransaction tx = session.BeginTransaction())
{
const string CONST_STR_FIRSTNAME = "Stephen";
const string CONST_STR_LASTNAME = "Manga";
DateTime birthdate = new DateTime(1974, 6, 20);
Person p = new Person
{
FirstName = CONST_STR_FIRSTNAME,
LastName = CONST_STR_LASTNAME,
Birthdate = birthdate
};
session.SaveOrUpdate(p);
session.Flush();
tx.Commit();
}
}
}
}
}
Edit:
After some reading I've come to the understanding that Distributed Transaction Coordinator has to be enabled. After starting this service and testing still no success :(
You have a COMMIT statement in your code. Perhaps you should remove that.
I use Proteus it does just fine. Easy to setup and use..
All you need is to add some code to Setups TearDowns and prepare folder with 'snapshot' of your database.
Why not just let System.Transactions.TransactionScope handle it?
using (new TransactionScope())
{
// do stuff that gets automatically rolled back
}
Alternatively, this seems to be exactly what the MbUnit Rollback2 attribute does anyway (Rollback uses EnterpriseServices/COM+ and is aimed at .NET 1.1).
Related
I don't know why this test fails. I created a new function, tested it manually and it works fine.
After that, I attempted to create test, but it always fails.
I don't know why.
It just should clear all records from DB older than 1,5 year, but variable historyToDelete always has 0 records. There is whole test:
using Microsoft.EntityFrameworkCore;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TeamsAllocationManager.Contracts.EmployeeWorkingTypeHistory;
using TeamsAllocationManager.Database;
using TeamsAllocationManager.Domain.Models;
using TeamsAllocationManager.Infrastructure.Handlers.EmployeeWorkingHistory;
namespace TeamsAllocationManager.Tests.Handlers.EmployeeWorkingHistory
{
[TestFixture]
public class ClearOldEmployeeWorkingTypeHistoryRecordsHandlerTest
{
private readonly ApplicationDbContext _context;
public ClearOldEmployeeWorkingTypeHistoryRecordsHandlerTest()
{
DbContextOptions<ApplicationDbContext> options = new DbContextOptionsBuilder<ApplicationDbContext>()
.UseInMemoryDatabase(databaseName: GetType().Name)
.Options;
_context = new ApplicationDbContext(options);
}
[SetUp]
public void SetupBeforeEachTest()
{
_context.ClearDatabase();
var employeeWorkingTypeHistory1 = new EmployeeWorkingTypeHistoryEntity
{
EmployeeId = Guid.Parse("d6951ec1-c865-41bb-8b83-0fcd81745579"),
WorkspaceType = 0,
Created = new DateTime(2000, 01, 01)};
var employeeWorkingTypeHistory2 = new EmployeeWorkingTypeHistoryEntity
{
EmployeeId = Guid.Parse("8a6c4e1c-2c6d-4b70-a507-7bdae5f75429"),
WorkspaceType = 0,
Created = DateTime.Now
};
_context.EmployeeWorkingTypeHistory.Add(employeeWorkingTypeHistory1);
_context.EmployeeWorkingTypeHistory.Add(employeeWorkingTypeHistory2);
_context.SaveChanges();
}
[Test]
public async Task ShouldClearHistory()
{
// given
int numberOfHistoryToClear = 1;
int expectedInDatabase = _context.EmployeeWorkingTypeHistory.Count() - numberOfHistoryToClear;
var command = new ClearOldEmployeeWorkingTypeHistoryRecordsCommand();
var deletionDate = command.TodayDate.AddMonths(-18);
var historyToDelete = await _context.EmployeeWorkingTypeHistory
.Where(ewth => deletionDate > ewth.Created)
.ToListAsync();
var commandHandler = new ClearOldEmployeeWorkingTypeHistoryRecordsHandler(_context);
// when
bool result = await commandHandler.HandleAsync(command);
// then
Assert.IsTrue(result);
Assert.AreEqual(expectedInDatabase, _context.EmployeeWorkingTypeHistory.Count());
//Assert.IsFalse(_context.EmployeeWorkingTypeHistory.Any(ewth => historyToDelete.Contains(ewth.Id)));
}
}
}
If I found out why it fails, I will fix whole test but now I am stuck.
#Update 1
I found a issue. When im creating dbContext in SetupBeforeEachTest, im setting up Created to 2000.01.01. There is everything ok, but when im going out from this to the first test, when i checking up a DB i always have current date, not provided in SetupBeforeEach (2021.12.27)
SaveChanges when creating record updating Created date, so if you want to change Created date to test in future, you need to create new record first, then save changes, update it and save changes again.
Try to call the SetupBeforeEachTest() method in your ShouldClearHistory() method.
I'm making an app with xamarin.forms and I have an issue with unit testing part. The problem is that when the test case runs isolated it passes, but when I run all the tests it fails.
using EmpresaPersonal.Modelos;
using EmpresaPersonal.ModelosVisuales;
using EmpresaPersonal.Services;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xunit;
namespace EmpresaPersonal.Test
{
public class PruebasVMEditarContacto
{
[Fact]
public async Task GuardarContactoSeteaCorrectamenteAsync()
{
// Preparamos el editor y los eventos
var store = new MockDataStore();
var mockNavegacion = ServiciosFalsos.MockIrAtras();
var editor = new MVEditarContacto(store, mockNavegacion.Object)
{
// Initializer setters...
};
bool llamado = false;
MessagingCenter.Subscribe<MVEditarContacto, string>(this, MVEditarContacto.EventoContactoCreado, async (s, idContacto) => // This line throws a NullReferenceException
{
var contacto = await store.GetItemAsync(idContacto);
// Algunos chequeos van por acá
Assert.NotNull(contacto);
Assert.Equal(editor.Nombre.Valor, contacto.Nombre);
Assert.Equal(editor.Empresa.Valor, contacto.Empresa);
Assert.Equal(editor.TelefonoPrincipal.Valor, contacto.TelefonoPrincipal);
Assert.Equal(editor.TelefonoSecundario.Valor, contacto.TelefonoSecundario);
llamado = true;
});
editor.GuardarContacto.Execute(null);
await editor.EsperarCompletarAsync();
Assert.True(llamado, "El evento no fue llamado.");
mockNavegacion.Verify(m => m.AtrasAsync());
}
}
}
I don't use anything than MessagingCenter.Send` from the model instantiated in this chunk. I have to say that I have another test for a model that subscribes to this model, to the same event in it's constructor (the model is the subscriber).
Any ideas?
I saw that when unit testing very xamarin.forms related code such MessagingCenter, the best way is to run the tests from Xunit.Runner.Devices test runner (A.C.A. with a real and initialized xamarin.forms environment).
The best example I've found is the EShop on containers mobile app.
I've just left my project and started a new one heavily based on Prism.Forms to ease unit testing these kind of things because it is constructed on top of IOC containers.
So I have written a plugin to do some simple calculations and and update fields based upon certain conditions. The plugin compiles and doesn't cause any errors while profiling or create any instances where I can debug my code which is frustrating. Anyways without further ado here it is:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BPT.PluginCommon.BaseClasses;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using Xrm;
namespace Engage.Crm.Plugins
{
public class VoidPayment : BPTPluginBase
{
bpt_DuesHeader oDuesHeader = new bpt_DuesHeader();
Account org = new Account();
public override void HandleAfterOp()
{
try
{
base.HandleAfterOp();
var crmContext = new XrmServiceContext(this.OrganizationService);
if (this.PluginExecutionContext.MessageName == MessageName.Create ||
this.PluginExecutionContext.MessageName == MessageName.Update)
{
if (this.InputTargetEntity.Attributes.Contains("gih_void"))
{
var Void = (bool) this.InputTargetEntity.Attributes["gih_void"];
var voidReason = (OptionSetValue) this.InputTargetEntity.Attributes["gih_voidreason"];
var totalPayments = (Money) this.InputTargetEntity.Attributes["bpt_TotalPayments"];
var amountBilled =
crmContext.bpt_DuesHeaderSet.Where(
o => o.bpt_DuesHeaderId == this.PluginExecutionContext.PrimaryEntityId)
.ToList()
.Sum(o => o.bpt_TotalAmountBilled == null ? 0 : o.bpt_TotalAmountBilled.Value);
if (Void)
{
this.oDuesHeader.bpt_TotalAdjustments = new Money(amountBilled);
this.oDuesHeader.bpt_TotalAmountBilled =
new Money(oDuesHeader.bpt_TotalAdjustments.Value + totalPayments.Value);
this.oDuesHeader.bpt_Balance = new Money(amountBilled);
if (voidReason.Value == 914020000)
//should be dropped not default option
{
oDuesHeader.gih_terminationdate = DateTime.Now;
}
}
OrganizationService.Update(oDuesHeader);
}
}
}
catch (Exception ex)
{
this.TracingService.Trace(this.ToString() + " {0}", "Exception: {0}", ex.ToString());
throw;
}
}
}
}
Sorry code is not formating well! Help! The plugin is registered as post-operation and synchronous. Any insight would be helpful and if a moderator could help format the code that would be greatly appreciated because it is not letting me add four spaces in certain places.
Plugins in CRM are created once, and then used multiple time, maybe even simultaneously, so besides setting the Id, don't use class level fields. You're creating a race condition that could really do some unwanted changes.
Looking at the sample code given on https://azure.microsoft.com/en-us/documentation/articles/hdinsight-hbase-tutorial-get-started/#use-the-net-hbase-rest-api-client-library,
I'm trying to connect to HBase from an MVC Controller as follows:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;
using Microsoft.HBase.Client;
using org.apache.hadoop.hbase.rest.protobuf.generated;
namespace MyHBaseTest.Controllers
{
[RoutePrefix("api/myhbasetestcontroller")]
public class MyHBaseTestController : ApiController
{
HBaseReader hbase = new HBaseReader();
[HttpGet]
[Route("")]
public IHttpActionResult Index()
{
string clusterURL = "https://<yourHBaseClusterName>.azurehdinsight.net";
string hadoopUsername = "<yourHadoopUsername>";
string hadoopUserPassword = "<yourHadoopUserPassword>";
// Create a new instance of an HBase client.
ClusterCredentials creds = new ClusterCredentials(new Uri(clusterURL), hadoopUsername, hadoopUserPassword);
HBaseClient hbaseClient = new HBaseClient(creds);
// Retrieve the cluster version
var version = hbaseClient.GetVersion();
Console.WriteLine("The HBase cluster version is " + version);
return Ok();
}
}
}
When I try to view the URL /api/myhbasetestcontroller in my browser when it is run in debug mode, it keeps loading the page forever without throwing any exception or anything in Visual Studio. I have waited for 15-20 minutes but nothing changes.
When I put try to do the same in a console application, it gets the version information in a matter of seconds though:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.HBase.Client;
using org.apache.hadoop.hbase.rest.protobuf.generated;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string clusterURL = "https://<yourHBaseClusterName>.azurehdinsight.net";
string hadoopUsername= "<yourHadoopUsername>";
string hadoopUserPassword = "<yourHadoopUserPassword>";
// Create a new instance of an HBase client.
ClusterCredentials creds = new ClusterCredentials(new Uri(clusterURL), hadoopUsername, hadoopUserPassword);
HBaseClient hbaseClient = new HBaseClient(creds);
// Retrieve the cluster version
var version = hbaseClient.GetVersion();
Console.WriteLine("The HBase cluster version is " + version);
}
}
}
I just don't understand how it makes a difference really.
Could you please advice?
Many thanks.
As of today, you need to run your calls on a background thread. I ran into this same exact issue. My calls are consolidated under a single function. I run that function on a background thread and everything works great.
// POST: api/Vizzini
[ResponseType(typeof(string))]
public async Task<IHttpActionResult> GetResponse(string tweet)
{
string s = await Task.Run(() =>
{
return ResponseEngine.GetBestResponse(tweet);
});
return Ok(s);
}
You are using blocking synchronous APIs, which won't work in the context of MVC/Web app (due to using wrong async context by default). You need to use async version of the methods. E.g. for GetVersion use GetVersionAsync.
I'm playing with Entity Framework, and I have a Unit Test project that I want to exercise what I've done so far. I'd like to have it not actually update my test database when it's done. If I was working in SQL I would create a transaction and then roll it back at the end.
How can I do the same thing here?
As I understand it, context.SaveChanges(); is effectively doing the write to the database. And if I don't have that, then allCartTypes is empty after I assign it context.CarTypes.ToList()
Here's an example of one of my Test classes.
using System;
using System.Diagnostics;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Trains;
using System.Linq;
namespace TrainsTest
{
[TestClass]
public class TestCarType : TestBase
{
[TestMethod]
public void TestCarTypeCreate_Success()
{
var tankerCarType = new CarType {Name = "Tanker"};
var boxCarType = new CarType { Name = "Box" };
using (var context = new TrainEntities())
{
context.CarTypes.Add(tankerCarType);
context.CarTypes.Add(boxCarType);
context.SaveChanges();
var allCartTypes = context.CarTypes.ToList();
foreach (var cartType in allCartTypes)
{
Debug.WriteLine(cartType.CarTypeId + " - " + cartType.Name);
}
}
}
}
}
I know I'm missing something fundamental, but I don't know what it is. and my googling has been fruitless.
There's a MSDN article about ef transactions.
http://msdn.microsoft.com/en-gb/library/vstudio/bb738523(v=vs.100).aspx