Closed DmitryMak closed 4 months ago
Can you write a sample failing test case showing the problem please?
I'm not sure how I can write a test that controls the Culture of the runner. But to explain what I mean:
public class Sut {
public String Format() {
return 1_000.ToString("C", CultureInfo.CurrentCulture);
}
}
[Subject(typeof(Sut))]
public class when_formatting {
Establish context = () =>
_subject = new();
Because of = () =>
_formatted = _subject.Format();
// will fail if runner is not en-US, or OS regional settings use different currency symbol
It should_format_using_current_culture = () =>
_formatted.ShouldEqual("$1,000.00");
static Sut _subject;
static String _formatted;
}
I don't think this is anything to do with the runner or the Should
handlers. You should be able to control the culture yourself. For example, the below tests will pass using your example:
public class Sut
{
public String Format()
{
return 1_000.ToString("C", CultureInfo.CurrentCulture);
}
}
[Subject(typeof(Sut))]
public class when_formatting
{
private Establish context = () =>
{
_subject = new();
// Set the current culture for the tests
CultureInfo.CurrentCulture = new CultureInfo("en-US");
};
Because of = () =>
_formatted = _subject.Format();
// will fail if runner is not en-US, or OS regional settings use different currency symbol
It should_format_using_current_culture = () =>
_formatted.ShouldEqual("$1,000.00");
static Sut _subject;
static String _formatted;
}
Yes, we can control the culture, in fact this is what we do as a workaround. Not only do we need to set it explicitly, we also need to restore it (in the Cleanup after
section). It adds noise to the spec and distracts from the actual code. I think this is the reason NUnit, for example, has this attribute
The SetCulture attribute is used to set the current Culture for the duration of a test. It may be specified at the level of a test, fixture or assembly. The culture remains set until the test or fixture completes and is then reset to its original value.
Have you looked into the lifecycle options for mspec? There is an example there that caters for culture-aware testing. See https://github.com/machine/machine.specifications/wiki/Advanced-Lifecycle-Options#iassemblycontext
Thanks for sharing. I think IAssemblyContext
is good for setting up a default culture. But sometimes the culture has to be specified at the individual spec level. A lot of other test frameworks implement this as an attribute.
Again, as above, you can do this via your Context
. You can nest multiple spec classes within an outer context to reduce on copy+paste if that is the concern. I'm not keen on adding additional attributes or constructs for niche use cases such as this.
Closing as answered.
There seem to be no standard way to set a Culture for a spec. Basically the specs end up inheriting Culture from a runner.
Could you add something like NUnit's SetCulture attribute