MemberAutoDataAttribute only auto generates values every second execution - xunit

I tried to combine the member-data and auto data attribute this way:
using Xunit;
using Ploeh.AutoFixture.Xunit2;
class MemberAutoDataAttribute : CompositeDataAttribute
{
public MemberAutoDataAttribute(string memberName)
: base(
new MemberDataAttribute(memberName),
new AutoDataAttribute())
{
}
}
This is the test which implements it:
[Theory, MemberAutoData(nameof(CurrentWeatherResponses))]
public void ParseCurrentWeather_WeatherParsed(
string response,
Weather expectedWeather,
TemperatureUnit tempUnit)
{
// ...
}
And here is the CurrentWeatherResponses member:
public static IEnumerable<object[]> CurrentWeatherResponses
{
get
{
yield return
new object[]
{
CurrentWeatherResponse.ToString(),
new Weather() {}
};
}
}
Why every second test execution all values are generated and not only the temperature unit?

Related

Issue getting fault message from message context in Masstransit

I have an application that needs to intercept the current message consume context and extract a value that is defined in a base interface. That value is a tenant code that is eventually used in an EF database context.
I have a provider that takes a MassTransit ConsumerContext, and then using context.TryGetMessage(), extracts the tenant code, which is ultimately used to switch database contexts to a specific tenant database.
The issue lies in the MessageContextTenantProvider below. If a non-fault message is consumed then ConsumeContext<IBaseEvent> works fine. However if it is a fault, ConsumeContext<Fault<IBaseEvent>> doesn't work as expected.
Durring debugging I can see that the message context for a fault is ConsumeContext<Fault<IVerifyEvent>>, but why doesn't it work with a base interface as per the standard message? Of course, ConsumeContext<Fault<IVerifiedEvent>> works fine, but I have a lot of message types, and I don't want to have to define them all in that tenant provider.
Any ideas?
public interface ITenantProvider
{
string GetTenantCode();
}
public class MessageContextTenantProvider : ITenantProvider
{
private readonly ConsumeContext _consumeContext;
public MessageContextTenantProvider(ConsumeContext consumeContext)
{
_consumeContext = consumeContext;
}
public string GetTenantCode()
{
// get tenant from message context
if (_consumeContext.TryGetMessage(out ConsumeContext<IBaseEvent> baseEvent))
{
return baseEvent.Message.TenantCode; // <-- works for the non fault consumers
}
// get tenant from fault message context
if (_consumeContext.TryGetMessage<Fault<IBaseEvent>>(out var gebericFaultEvent))
{
return gebericFaultEvent.Message.Message.TenantCode; // <- doesn't work generically
}
// get tenant from fault message context (same as above)
if (_consumeContext.TryGetMessage(out ConsumeContext<Fault<IBaseEvent>> faultEvent))
{
return faultEvent.Message.Message.TenantCode; // <= generically doesn't work when using the base interface?
}
// get tenant from specific concrete fault class
if (_consumeContext.TryGetMessage(out ConsumeContext<Fault<IVerifiedEvent>> verifiedFaultEvent))
{
return verifiedFaultEvent.Message.Message.TenantCode; // <-- this works
}
// not able to extract tenant
return null;
}
}
public partial class VerificationDbContext
{
string connectionString;
public string ConnectionString
{
get
{
if (connectionString == null)
{
string tenantCode = _tenantProvider.GetTenantCode();
connectionString = _tenantConnectionManager.GetConnectionString(orgId);
}
return connectionString;
}
}
private readonly ITenantProvider _tenantProvider;
private readonly ITenantConnectionManager _tenantConnectionManager;
public VerificationDbContext(ITenantProvider tenantProvider, ITenantConnectionManager tenantConnectionManager)
{
_tenantProvider = tenantProvider;
_tenantConnectionManager = tenantConnectionManager;
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (string.IsNullOrEmpty(this.ConnectionString))
{
optionsBuilder.UseSqlServer(#"Data Source=.\SQLEXPRESS;Initial Catalog=VerificationDb;Integrated Security=True")
.ConfigureWarnings((warningBuilder) => warningBuilder.Ignore(RelationalEventId.AmbientTransactionWarning));
}
else
{
optionsBuilder.UseSqlServer(this.ConnectionString)
.ConfigureWarnings((warningBuilder) => warningBuilder.Ignore(RelationalEventId.AmbientTransactionWarning));
}
}
}
public interface ITenantConnectionManager
{
string GetConnectionString(string tenantCode);
}
public class TenantConnectionManager : ITenantConnectionManager
{
private ITenantRepository _tenantRepository;
public TenantConnectionManager(ITenantRepository tenantRepository)
{
_tenantRepository = tenantRepository;
}
public string GetConnectionString(string tenantCode)
{
return _tenantRepository.GetByTenantCode(tenantCode).ConnectionString;
}
}
public interface IBaseEvent
{
string TenantCode { get; }
}
public interface IVerifiedEvent : IBaseEvent
{
string JobReference { get; }
}
public class VerifiedEventConsumer : IConsumer<IVerifiedEvent>
{
private readonly IVerifyCommand _verifyCommand;
private readonly ITenantProvider _tenantProvider;
public VerifiedEventConsumer(ITenantProvider tenantProvider, IVerifyCommand verifyCommand)
{
_verifyCommand = verifyCommand;
_tenantProvider = tenantProvider;
}
public async Task Consume(ConsumeContext<IVerifiedEvent> context)
{
await _verifyCommand.Execute(new VerifyRequest
{
JobReference = context.Message.JobReference,
TenantCode = context.Message.TenantCode
});
}
}
public class VerifiedEventFaultConsumer : IConsumer<Fault<IVerifiedEvent>>
{
private readonly IVerifyFaultCommand _verifyFaultCommand;
private readonly ITenantProvider _tenantProvider;
public CaseVerifiedEventFaultConsumer(ITenantProvider tenantProvider, IVerifyFaultCommand verifyFaultCommand)
{
_verifyFaultCommand = verifyFaultCommand;
_tenantProvider = tenantProvider;
}
public async Task Consume(ConsumeContext<Fault<ICaseVerifiedEvent>> context)
{
await _verifyFaultCommand.Execute(new VerifiedFaultRequest
{
JobReference = context.Message.Message.JobReference,
Exceptions = context.Message.Exceptions
});
}
}
I've solved the issue by using the GreenPipes TryGetPayload extension method:
public class MessageContextTenantProvider : ITenantProvider
{
private readonly ConsumeContext _consumeContext;
public MessageContextTenantProvider(ConsumeContext consumeContext)
{
_consumeContext = consumeContext;
}
public string GetTenantCode()
{
// get tenant from message context
if (_consumeContext.TryGetMessage(out ConsumeContext<IBaseEvent> baseEvent))
{
return baseEvent.Message.TenantCode;
}
// get account code from fault message context using Greenpipes
if (_consumeContext.TryGetPayload(out ConsumeContext<Fault<IBaseEvent>> payloadFaultEvent))
{
return payloadFaultEvent.Message.Message.TenantCode;
}
// not able to extract tenant
return null;
}
}

I am getting following error : "The following constructor parameters did not have matching fixture data: AddressValidator addressValidator"

ValidatorTest class having common methods for all the validations.
Test case get passed but after passing I am getting this error.
I can write extension methods which can do this job but I am not getting what is going wrong with xunit. Any help is appreciated.
namespace TestSuite.Validator
{
public abstract class ValidatorTest<TClass,TClassValidator> where TClassValidator: AbstractValidator<TClass>
{
private readonly TClassValidator _tClassValidator;
public ValidatorTest(TClassValidator validator)
{
_tClassValidator = validator;
}
public void Address_Should_ReturnValidationError_When_MandatoryFieldsAreNotPassed(TClass address, List<KeyValuePair<string, string>> expectedErrors)
{
var validationResult = _tClassValidator.Validate(address);
Assert.False(validationResult.IsValid);
foreach (var expectedError in expectedErrors)
{
Assert.Contains(validationResult.Errors, (actualError) => actualError.ErrorMessage.Equals(expectedError.Value) && actualError.ErrorCode.Equals(expectedError.Key));
}
foreach (var actualError in validationResult.Errors)
{
Assert.Contains<KeyValuePair<string, string>>(expectedErrors, expectedError => expectedError.Value.Equals(actualError.ErrorMessage) && expectedError.Key.Equals(actualError.ErrorCode));
}
}
public void Address_Should_Pass_When_MandatoryFieldsArePassed(TClass address)
{
var validationResult = _tClassValidator.Validate(address);
Assert.True(validationResult.IsValid);
Assert.Empty(validationResult.Errors);
}
}
}
namespace TestSuite.Validator
{
public class AddressValidatorTest : ValidatorTest<Address, AddressValidator>
{
public AddressValidatorTest(AddressValidator addressValidator) : base(new AddressValidator())
{
}
[Theory]
[JsonDataReaderAttribute("AddressValidatorData", "Valid")]
public void PositiveTest(Address address)
{
Address_Should_Pass_When_MandatoryFieldsArePassed(address);
}
}
}
I just had a similar error and it was because I forgot to implement IClassFixture on my test class.

Merging multiple custom observables in RX

Trying to model a system sending out notifications from a number of publishers using RX.
I have two custom interfaces ITopicObservable and ITopicObserver to model the fact that the implementing classes will have other properties and methods apart from the IObservable and IObserver interfaces.
The problem I have is that my thinking is I should be able to add a number of observables together, merge them together and subscribe to an observer to provide updates from all merged observables. However the code with "the issue" comment throws an invalid cast exception.
The use case is a number of independent sensors each monitoring a temperature in a box for example that aggregate all their reports to one temperature report which is then subscribed to by a temperature health monitor.
What am I missing here? Or is there a better way to implement the scenario using RX?
Code below
using System;
using System.Reactive.Linq;
using System.Collections.Generic;
namespace test
{
class MainClass
{
public static void Main (string[] args)
{
Console.WriteLine ("Hello World!");
var to = new TopicObserver ();
var s = new TopicObservable ("test");
var agg = new AggregatedTopicObservable ();
agg.Add (s);
agg.Subscribe (to);
}
}
public interface ITopicObservable<TType>:IObservable<TType>
{
string Name{get;}
}
public class TopicObservable:ITopicObservable<int>
{
public TopicObservable(string name)
{
Name = name;
}
#region IObservable implementation
public IDisposable Subscribe (IObserver<int> observer)
{
return null;
}
#endregion
#region ITopicObservable implementation
public string Name { get;private set;}
#endregion
}
public class AggregatedTopicObservable:ITopicObservable<int>
{
List<TopicObservable> _topics;
private ITopicObservable<int> _observable;
private IDisposable _disposable;
public AggregatedTopicObservable()
{
_topics = new List<TopicObservable>();
}
public void Add(ITopicObservable<int> observable)
{
_topics.Add ((TopicObservable)observable);
}
#region IObservable implementation
public IDisposable Subscribe (IObserver<int> observer)
{
_observable = (ITopicObservable<int>)_topics.Merge ();
_disposable = _observable.Subscribe(observer);
return _disposable;
}
#endregion
#region ITopicObservable implementation
public string Name { get;private set;}
#endregion
}
public interface ITopicObserver<TType>:IObserver<TType>
{
string Name{get;}
}
public class TopicObserver:ITopicObserver<int>
{
#region IObserver implementation
public void OnNext (int value)
{
Console.WriteLine ("next {0}", value);
}
public void OnError (Exception error)
{
Console.WriteLine ("error {0}", error.Message);
}
public void OnCompleted ()
{
Console.WriteLine ("finished");
}
#endregion
#region ITopicObserver implementation
public string Name { get;private set;}
#endregion
}
}
My first thought, is that you shouldn't implement IObservable<T>, you should compose it by exposing it as a property or the result of a method.
Second thought is that there are operators in Rx that excel at merging/aggregating multiple sequences together.
You should favor using those.
Third, which is similar to the first, you generally don't implement IObserver<T>, you just subscribe to the observable sequence and provide delegates for each call back (OnNext, OnError and OnComplete)
So your code basically is reduced to
Console.WriteLine("Hello World!");
var topic1 = TopicListener("test1");
var topic2 = TopicListener("test2");
topic1.Merge(topic2)
.Subscribe(
val => { Console.WriteLine("One of the topics published this value {0}", val);},
ex => { Console.WriteLine("One of the topics errored. Now the whole sequence is dead {0}", ex);},
() => {Console.WriteLine("All topics have completed.");});
Where TopicListener(string) is just a method that returns IObservable<T>.
The implementation of the TopicListener(string) method would most probably use Observable.Create.
It may help to see examples of mapping Rx over a Topic based messaging system.
There is an example of how you can layer Rx over TibRv topics here https://github.com/LeeCampbell/RxCookbook/blob/master/IO/Comms/TibRvSample.linq
The signature of the .Merge(...) operator that you're using is:
IObservable<TSource> Merge<TSource>(this IEnumerable<IObservable<TSource>> sources)
The actual type returned by this .Merge() is:
System.Reactive.Linq.ObservableImpl.Merge`1[System.Int32]
...so it should be fairly clear that calling (ITopicObservable<int>)_topics.Merge(); would fail.
Lee's advice not to implement either of IObservable<> or IObserver<> is the correct one. It leads to errors like the one above.
If you had to do something like this, I would do it this way:
public interface ITopic
{
string Name { get; }
}
public interface ITopicObservable<TType> : ITopic, IObservable<TType>
{ }
public interface ITopicSubject<TType> : ISubject<TType>, ITopicObservable<TType>
{ }
public interface ITopicObserver<TType> : ITopic, IObserver<TType>
{ }
public class Topic
{
public string Name { get; private set; }
public Topic(string name)
{
this.Name = name;
}
}
public class TopicSubject : Topic, ITopicSubject<int>
{
private Subject<int> _subject = new Subject<int>();
public TopicSubject(string name)
: base(name)
{ }
public IDisposable Subscribe(IObserver<int> observer)
{
return _subject.Subscribe(observer);
}
public void OnNext(int value)
{
_subject.OnNext(value);
}
public void OnError(Exception error)
{
_subject.OnError(error);
}
public void OnCompleted()
{
_subject.OnCompleted();
}
}
public class AggregatedTopicObservable : Topic, ITopicObservable<int>
{
List<ITopicObservable<int>> _topics = new List<ITopicObservable<int>>();
public AggregatedTopicObservable(string name)
: base(name)
{ }
public void Add(ITopicObservable<int> observable)
{
_topics.Add(observable);
}
public IDisposable Subscribe(IObserver<int> observer)
{
return _topics.Merge().Subscribe(observer);
}
}
public class TopicObserver : Topic, ITopicObserver<int>
{
private IObserver<int> _observer;
public TopicObserver(string name)
: base(name)
{
_observer =
Observer
.Create<int>(
value => Console.WriteLine("next {0}", value),
error => Console.WriteLine("error {0}", error.Message),
() => Console.WriteLine("finished"));
}
public void OnNext(int value)
{
_observer.OnNext(value);
}
public void OnError(Exception error)
{
_observer.OnError(error);
}
public void OnCompleted()
{
_observer.OnCompleted();
}
}
And run it with:
var to = new TopicObserver("watching");
var ts1 = new TopicSubject("topic 1");
var ts2 = new TopicSubject("topic 2");
var agg = new AggregatedTopicObservable("agg");
agg.Add(ts1);
agg.Add(ts2);
agg.Subscribe(to);
ts1.OnNext(42);
ts1.OnCompleted();
ts2.OnNext(1);
ts2.OnCompleted();
Which gives:
next 42
next 1
finished
But apart from being able to give everything a name (which I'm not sure how it helps) you could always do this:
var to =
Observer
.Create<int>(
value => Console.WriteLine("next {0}", value),
error => Console.WriteLine("error {0}", error.Message),
() => Console.WriteLine("finished"));
var ts1 = new Subject<int>();
var ts2 = new Subject<int>();
var agg = new [] { ts1, ts2 }.Merge();
agg.Subscribe(to);
ts1.OnNext(42);
ts1.OnCompleted();
ts2.OnNext(1);
ts2.OnCompleted();
Same output with no interfaces and classes.
There's even a more interesting way. Try this:
var to =
Observer
.Create<int>(
value => Console.WriteLine("next {0}", value),
error => Console.WriteLine("error {0}", error.Message),
() => Console.WriteLine("finished"));
var agg = new Subject<IObservable<int>>();
agg.Merge().Subscribe(to);
var ts1 = new Subject<int>();
var ts2 = new Subject<int>();
agg.OnNext(ts1);
agg.OnNext(ts2);
ts1.OnNext(42);
ts1.OnCompleted();
ts2.OnNext(1);
ts2.OnCompleted();
var ts3 = new Subject<int>();
agg.OnNext(ts3);
ts3.OnNext(99);
ts3.OnCompleted();
This produces:
next 42
next 1
next 99
It allows you to add new source observables after the merge!

NHibernate LINQ Add Query Hints

I'm trying to add "OPTION(RECOMPILE)" to the end of some of my NHibernate queries. I found the following post:
http://www.codewrecks.com/blog/index.php/2011/07/23/use-sql-server-query-hints-with-nhibernate-hql-and-icriteria/
This describes how I can add an interceptor to append the SQL. However they are using ICriteria whereas I use LINQ to query my data. Ideally I'd like to be able to say something like:
var query = session.Query<Foo>().OptionRecompile().ToList();
I was wondering if it's possible to add an extension method to IQueryable which will inject some string into the query which I can then detect for in my interceptor. This is similar to the approach used in the article above where they add a comment and detect for that.
For further information. I've dealt with LINQ extensions before and I know you can add extension properties/methods using a HQL generator. But from my understanding this will only allow me to say:
var query = session.Query<Foo>().Where(f => f.Bar.OptionRecompile()).ToList();
This isn't ideal and seems more of a hack. I'd appreciate it if someone can help. Thanks
I ran into this issue recently, too. We came up with a fairly decent/robust solution. The important thing is that it utilizes Rhino.Commons.LocalData to provide an execution scope.
// First part
using System;
using System.Collections;
using System.Web;
using Rhino.Commons.LocalDataImpl;
namespace Rhino.Commons
{
/// <summary>
/// This class is key for handling local data, data that is private
/// to the current context, be it the current thread, the current web
/// request, etc.
/// </summary>
public static class Local
{
static readonly ILocalData current = new LocalData();
static readonly object LocalDataHashtableKey = new object();
private class LocalData : ILocalData
{
[ThreadStatic]
static Hashtable thread_hashtable;
private static Hashtable Local_Hashtable
{
get
{
if (!RunningInWeb)
{
return thread_hashtable ??
(
thread_hashtable = new Hashtable()
);
}
Hashtable web_hashtable = HttpContext.Current.Items[LocalDataHashtableKey] as Hashtable;
if(web_hashtable==null)
{
HttpContext.Current.Items[LocalDataHashtableKey] = web_hashtable = new Hashtable();
}
return web_hashtable;
}
}
public object this[object key]
{
get { return Local_Hashtable[key]; }
set { Local_Hashtable[key] = value; }
}
public void Clear()
{
Local_Hashtable.Clear();
}
}
/// <summary>
/// Gets the current data
/// </summary>
/// <value>The data.</value>
public static ILocalData Data
{
get { return current; }
}
/// <summary>
/// Gets a value indicating whether running in the web context
/// </summary>
/// <value><c>true</c> if [running in web]; otherwise, <c>false</c>.</value>
public static bool RunningInWeb
{
get { return HttpContext.Current != null; }
}
}
}
// Second part
using System;
using Rhino.Commons;
namespace IDL.Core.Util.NHibernate
{
public class NhSqlAppender : IDisposable
{
private static string sql;
private int usages = 1;
public NhSqlAppender()
{
}
public NhSqlAppender(string sqlToAppend)
{
sql = sqlToAppend;
}
public static NhSqlAppender Append(string sqlToAppend)
{
var currentAppender = Current;
if (currentAppender == null)
{
Current = new NhSqlAppender(sqlToAppend);
currentAppender = Current;
}
else
currentAppender.IncrementUsages();
return currentAppender;
}
public static NhSqlAppender Current
{
get { return Local.Data["NhSqlAppender"] as NhSqlAppender; }
protected set { Local.Data["NhSqlAppender"] = value; }
}
public static string Sql
{
get { return (IsValid) ? sql : string.Empty; }
}
public static bool AppendSql
{
get { return IsValid; }
}
public void IncrementUsages()
{
++usages;
}
public void DecrementUsages()
{
--usages;
}
private static bool IsValid
{
get { return (Current != null && !string.IsNullOrWhiteSpace(sql)); }
}
public void Dispose()
{
if (usages <= 1)
Current = null;
else
DecrementUsages();
}
}
}
// Third part
namespace IDL.Core.Util.NHibernate
{
public class NhQueryHint : NhSqlAppender
{
public static NhSqlAppender Recompile()
{
return Append("OPTION(RECOMPILE)");
}
}
}
// Fourth part
using System;
using IDL.Core.Util.NHibernate;
using NHibernate;
namespace IDL.Core.Configuration
{
[Serializable]
public class NhSqlAppenderInterceptor : EmptyInterceptor
{
public override NHibernate.SqlCommand.SqlString OnPrepareStatement(NHibernate.SqlCommand.SqlString sql)
{
if (NhSqlAppender.AppendSql)
return sql.Insert(sql.Length, (" " + NhSqlAppender.Sql));
return base.OnPrepareStatement(sql);
}
}
}
// Fifth part
// You need to register the interceptor with NHibernate
// cfg = NHibernate.Cfg.Configuration
cfg.SetInterceptor(new NhSqlAppenderInterceptor());
// Finally, usage
using (NhQueryHint.Recompile())
var results = IQueryable<T>.ToList();
You'll have to modify to fit your environment. Hope it helps!
The accepted answer above by #jvukovich helped my out a lot. I built upon his answer by encapsulating the usage of the Recompile hint in an extension method as shown below.
// Extension Method
public static class NhQueryHintExtensions
{
public static TReturn Recompile<T, TReturn>(this IQueryable<T> queryable, Func<IQueryable<T>, TReturn> toFunction)
{
using (NhQueryHint.Recompile())
{
return toFunction(queryable);
}
}
}
// Usage
var results = IQueryable<T>.Recompile(x => x.ToList());

How to Mock a Delegate Action Input Parameter

I am trying to arrange the input parameter of the lambda that is passed to ICallback#Regsiter<T>(Action<T>) in the (paired down) unit test sample below (see the comments in the unit test sample). I am trying to avoid having to abstract out the lambda because it's so specific and small, but I'm not sure if that's possible.
// IBus interface peek
public interface IBus {
ICallback Send(IMessage message);
}
// ICallback interface peek
public interface ICallback {
void Register<T>(Action<T> callback);
}
public enum ReturnCode { Success }
// Controller
public class FooController : AsyncController {
readonly IBus _bus;
//...
// Action being unit tested
public void BarAsync() {
_bus
.Send(ZapMessageFactory.Create())
.Register<ReturnCode>(x => {
AsyncManger.Parameters["returnCode"] = x;
});
}
public ActionResult BarCompleted(ReturnCode returnCode) {
// ...
}
}
// Controller action unit test
[TestClass]
public class FooControllerTest {
[TestMethod}
public void BarTestCanSetAsyncManagerParameterErrorCodeToSuccess() {
var fooController = ControllerUTFactory.CreateFooController();
// HOW DO I MOCK THE ACTION DELEGATE PARAMETER TO BE ReturnCode.Success
// SO I CAN DO THE ASSERT BELOW???
fooController.BarAsync();
Assert.AreEqual(ReturnCode.Success, (ReturnCode)fooController.AsyncManager.Parameters["returnCode"]);
}
}
Using the Mock<T>#Callback() is the answer:
[TestMethod}
public void BarTestCanSetAsyncManagerParameterErrorCodeToSuccess() {
var mockCallback = new Mock<ICallback>();
mockCallback
.Setup(x => x.Register(It.IsAny<ReasonCode>())
// THIS LINE IS THE ANSWER
.Callback(action => action(ReasonCode.Success));
var mockBus = new Mock<IBus>();
mockBus
.Setup(x => x.Send(It.IsAny<ZapMessage>())
.Returns(mockCallback.Object);
var fooController = new FooController(mockBus.Object);
fooController.BarAsync();
Assert.AreEqual(ReturnCode.Success, (ReturnCode)fooController.AsyncManager.Parameters["returnCode"]);
}

Resources