Lets say I have:
an object to be tested (it utilizes RX inside);
number of test object dependencies, that utilize RX too - created using MOQ.
The question is:
is this an erroneous approach to use the same TestScheduler instance to control timings within the test object and for external observables?
Thanks in advance
For any specific test, you should (and must!) use the same TestScheduler for every object / method that requires / can take an IScheduler, or else It Doesn't Work.™ ReactiveUI does this via having a global "MainThreadScheduler" object that can be overridden at test time, so you can do things like:
var oldSched = RxApp.MainThreadScheduler;
RxApp.MainThreadScheduler = new TestScheduler();
// Do a Test, and make sure all your test and runtime code use RxApp schedulers
RxApp.MainThreadScheduler = oldSched;
Or, the more elegant RxUI way is via .With()
(new TestScheduler()).With(sched => {
// Do a test here.
});
Related
I am writing unit tests for a complex application which has so many rules to be checked into a single flow by using NUnit and Playwright in .Net5. Actually the case is, to save the time for writing the test scripts for Playwright (front-end testing tool), we have used a library named Bogus to create dummy data dynamically based on the rules (because the test cases has numerous rules to be checked and it was much more difficult to write fresh data to every case). I am using Playwright script into the NUnit test and providing the data source by using [TestCaseSource("MethodName")] to provide dynamic data object for different cases.
Now, we are facing a problem that some of the tests cases get passed and some are failed and we are unable to identify that particularly which test case is causing the problem because the testcase data is being provided by the dynamic source and in that source the data is being generated by the Bogus library on the bases of the rules which we have generated. Plus, we cannot look at the tests for a long time that's why we have automated the process.
[Test]
[TestCaseSource("GetDataToSubmit")]
public async Task Test_SubmitAssignmentDynamicFlow(Assignment assignment)
{
using var playwright = await Playwright.CreateAsync();
await using var browser = await playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions
{
Headless = false,
...
});
....
private static IEnumerable<TestCaseData> GetDataToSubmit()
{
//creating data for simple job
var simpleAssignment = new DummyAssigmentGenerator()
....
.Generate();
yield return new TestCaseData(simpleAssignment);
....
Now, my question is, is there any way so that we can view that what were the actual values in the object in the failed case, when we see the whole report of the testcases? So that we can come to know that which certain values are causing problems and eventually fixed those.
Two approaches...
Assuming that DummyAssignmentGenerator is your own class, override its ToString() method to display whatever you would like to see. That string will become part of the name of the test case generated, like...
Test_SubmitAssignmentDynamicFlow(YOUR_STRING)
Apply a name to each TestCaseData item you yield using the SetName() fluent method. In that case, you are supplying the full display name of the test case, not just the part in parentheses. Use {m}(YOUR_STRING) in order to have it appear the same as in the first approach.
If you can use it, the first approach is clearly the simpler of the two.
I am writing unit tests for some async sections of my code (returning Futures) that also involves the need to mock a Scala object.
Following these docs, I can successfully mock the object's functions. My question stems from the fact that withObjectMocked[FooObject.type] returns Unit, where async tests in scalatest require either an Assertion or Future[Assertion] to be returned. To get around this, I'm creating vars in my tests that I reassign within the function sent to withObjectMocked[FooObject.type], which ends up looking something like this:
class SomeTest extends AsyncWordSpec with Matchers with AsyncMockitoSugar with ResetMocksAfterEachAsyncTest {
"wish i didn't need a temp var" in {
var ret: Future[Assertion] = Future.failed(new Exception("this should be something")) // <-- note the need to create the temp var
withObjectMocked[SomeObject.type] {
when(SomeObject.someFunction(any)) thenReturn Left(Error("not found"))
val mockDependency = mock[SomeDependency]
val testClass = ClassBeingTested(mockDependency)
ret = testClass.giveMeAFuture("test_id") map { r =>
r should equal(Error("not found"))
} // <-- set the real Future[Assertion] value here
}
ret // <-- finally, explicitly return the Future
}
}
My question then is, is there a better/cleaner/more idiomatic way to write async tests that mock objects without the need to jump through this bit of a hoop? For some reason, I figured using AsyncMockitoSugar instead of MockitoSugar would have solved that for me, but withObjectMocked still returns Unit. Is this maybe a bug and/or a candidate for a feature request (the async version of withObjectMocked returning the value of the function block rather than Unit)? Or am I missing how to accomplish this sort of task?
You should refrain from using mockObject in a multi-thread environment as it doesn't play well with it.
This is because the object code is stored as a singleton instance, so it's effectively global.
When you use mockObject you're efectibly forcefully overriding this var (the code takes care of restoring the original, hence the syntax of usign it as a "resource" if you want).
Because this var is global/shared, if you have multi-threaded tests you'll endup with random behaviour, this is the main reason why no async API is provided.
In any case, this is a last resort tool, every time you find yourself using it you should stop and ask yourself if there isn't anything wrong with your code first, there are quite a few patterns to help you out here (like injecting the dependency), so you should rarely have to do this.
I have a dotnet core application.
My Startup.cs registers types/implementations in Autofac.
One of my registrations needs previous access to a service.
var containerBuilder = new ContainerBuilder();
containerBuilder.RegisterSettingsReaders(); // this makes available a ISettingsReader<string> that I can use to read my appsettings.json
containerBuilder.RegisterMyInfrastructureService(options =>
{
options.Username = "foo" //this should come from appsettings
});
containerBuilder.Populate(services);
var applicationContainer = containerBuilder.Build();
The dilemma is, by the time I have to .RegisterMyInfrastructureService I need to have available the ISettingsReader<string> that was registered just before (Autofac container hasn't been built yet).
I was reading about registering with callback to execute something after the autofac container has been built. So I could do something like this:
builder.RegisterBuildCallback(c =>
{
var stringReader = c.Resolve<ISettingsReader<string>>();
var usernameValue = stringReader.GetValue("Username");
//now I have my username "foo", but I want to continue registering things! Like the following:
containerBuilder.RegisterMyInfrastructureService(options =>
{
options.Username = usernameValue
});
//now what? again build?
});
but the problem is that after I want to use the service not to do something like starting a service or similar but to continue registering things that required the settings I am now able to provide.
Can I simply call again builder.Build() at the end of my callback so that the container is simply rebuilt without any issue? This seems a bit strange because the builder was already built (that's why the callback was executed).
What's the best way to deal with this dilemma with autofac?
UPDATE 1: I read that things like builder.Update() are now obsolete because containers should be immutable. Which confirms my suspicion that building a container, adding more registrations and building again is not a good practice.
In other words, I can understand that using a register build callback should not be used to register additional things. But then, the question remain: how to deal with these issues?
This discussion issue explains a lot including ways to work around having to update the container. I'll summarize here, but there is a lot of information in that issue that doesn't make sense to try and replicate all over.
Be familiar with all the ways you can register components and pass parameters. Don't forget about things like resolved parameters, modules that can dynamically put parameters in place, and so on.
Lambda registrations solve almost every one of these issues we've seen. If you need to register something that provides configuration and then, later, use that configuration as part of a different registration - lambdas will be huge.
Consider intermediate interfaces like creating an IUsernameProvider that is backed by ISettingsReader<string>. The IUsernameProvider could be the lambda (resolve some settings, read a particular one, etc.) and then the downstream components could take an IUsernameProvider directly.
These sorts of questions are hard to answer because there are a lot of ways to work around having to build/rebuild/re-rebuild the container if you take advantage of things like lambdas and parameters - there's no "best practice" because it always depends on your app and your needs.
Me, personally, I will usually start with the lambda approach.
I have several functions that deal with database interactions. (like readModelById, updateModel, findModels, etc) that I try to use in a functional style.
In OOP, I'd create a class that takes DB-connection-parameters in the constructor, creates the database-connection and save the DB-handle in the instance. The functions then would just use the DB-handle from "this".
What's the best way in FP to deal with this? I don't want to hand around the DB handle throughout the entire application. I thought about partial application on the functions to "bake in" the handle, but that creates ugly boilerplate code, doing it one by one and handing it back.
What's the best practice/design pattern for things like this in FP?
There is a parallel to this in OOP that might suggest the right approach is to take the database resource as parameter. Consider the DB implementation in OOP using SOLID principles. Due to Interface Segregation Principle, you would end up with an interface per DB method and at least one implementation class per interface.
// C#
public interface IGetRegistrations
{
public Task<Registration[]> GetRegistrations(DateTime day);
}
public class GetRegistrationsImpl : IGetRegistrations
{
public Task<Registration[]> GetRegistrations(DateTime day)
{
...
}
private readonly DbResource _db;
public GetRegistrationsImpl(DbResource db)
{
_db = db;
}
}
Then to execute your use case, you pass in only the dependencies you need instead of the whole set of DB operations. (Assume that ISaveRegistration exists and is defined like above).
// C#
public async Task Register(
IGetRegistrations a,
ISaveRegistration b,
RegisterRequest requested
)
{
var registrations = await a.GetRegistrations(requested.Date);
// examine existing registrations and determine request is valid
// throw an exception if not?
...
return await b.SaveRegistration( ... );
}
Somewhere above where this code is called, you have to new up the implementations of these interfaces and provide them with DbResource.
var a = new GetRegistrationsImpl(db);
var b = new SaveRegistrationImpl(db);
...
return await Register(a, b, request);
Note: You could use a DI framework here to attempt to avoid some boilerplate. But I find it to be borrowing from Peter to pay Paul. You pay as much in having to learn a DI framework and how to make it behave as you do for wiring the dependencies yourself. And it is another tech new team members have to learn.
In FP, you can do the same thing by simply defining a function which takes the DB resource as a parameter. You can pass functions around directly instead of having to wrap them in classes implementing interfaces.
// F#
let getRegistrations (db: DbResource) (day: DateTime) =
...
let saveRegistration (db: DbResource) ... =
...
The use case function:
// F#
let register fGet fSave request =
async {
let! registrations = fGet request.Date
// call your business logic here
...
do! fSave ...
}
Then to call it you might do something like this:
register (getRegistrations db) (saveRegistration db) request
The partial application of db here is analogous to constructor injection. Your "losses" from passing it to multiple functions is minimal compared to the savings of not having to define interface + implementation for each DB operation.
Despite being in a functional-first language, the above is in principle the same as the OO/SOLID way... just less lines of code. To go a step further into the functional realm, you have to work on eliminating side effects in your business logic. Side effects can include: current time, random numbers, throwing exceptions, database operations, HTTP API calls, etc.
Since F# does not require you to declare side effects, I designate a border area of code where side effects should stop being used. For me, the use case level (register function above) is the last place for side effects. Any business logic lower than that, I work on pushing side effects up to the use case. It is a learning process to do that, so do not be discouraged if it seems impossible at first. Just do what you have to for now and learn as you go.
I have a post that attempts to set the right expectations on the benefits of FP and how to get them.
I'm going to add a second answer here taking an entirely different approach. I wrote about it here. This is the same approach used by MVU to isolate decisions from side effects, so it is applicable to UI (using Elmish) and backend.
This is worthwhile if you need to interleave important business logic with side effects. But not if you just need to execute a series of side effects. In that case just use a block of imperative statements, in a task (F# 6 or TaskBuilder) or async block if you need IO.
The pattern
Here are the basic parts.
Types
Model - The state of the workflow. Used to "remember" where we are in the workflow so it can be resumed after side effects.
Effect - Declarative representation of the side effects you want to perform and their required data.
Msg - Represents events that have happened. Primarily, they are the results of side effects. They will resume the workflow.
Functions
update - Makes all the decisions. It takes in its previous state (Model) and a Msg and returns an updated state and new Effects. This is a pure function which should have no side effects.
perform - Turns a declared Effect into a real side effect. For example, saving to a database. Returns a Msg with the result of the side effect.
init - Constructs an initial Model and starting Msg. Using this, a caller gets the data it needs to start the workflow without having to understand the internal details of update.
I jotted down an example for a rate-limited emailer. It includes the implementation I use on the backend to package and run this pattern, called Ump.
The logic can be tested without any instrumentation (no mocks/stubs/fakes/etc). Declare the side effects you expect, run the update function, then check that the output matches with simple equality. From the linked gist:
// example test
let expected = [SendEmail email1; ScheduleSend next]
let _, actual = Ump.test ump initArg [DueItems ([email1; email2], now)]
Assert.IsTrue(expected = actual)
The integrations can be tested by exercising perform.
This pattern takes some getting-used-to. It reminds me a bit of an Erlang actor or a state machine. But it is helpful when you really need your business logic to be correct and well-tested. It also happens to be a proper functional pattern.
I'm wrapping my head around Akka from a node.js perspective. I do the following node.js code below, and it's easy to write & follow. I can easily extend to handle and aggregate multiple services async, all while holding onto initial argument state data (a in example).
function handleAction(a, b, callback) {
remoteServiceOperation(b, function(err, data) {
if (!err) {
// I can reference argument a
z = a + data; // Do work with a and service result
}
});
}
Below is rough pseudo for Akka/Scala. My understanding is ask ? blocks, and should be generally avoided. Attempting to illustrate where my knowledge train ends, and how I'm not clear about how to hold state a, aggregate (not-shown), or perhaps structure Akka in a node.js style in general.
receive {
case handleAction(a) =>
remoteService ! new RemoteServiceOperation(b, c)
// About to leave and we'll loose `a`
case remoteServiceOperationResponse(data) =>
// `a` is afk
}
How can I write Akka more like node?
I guess your callback well-known style of programming in nodejs maps better of use of Futures than Actors.
It looks like this:
val service1Res: Future[Int] = service1()
val service2Res: Future[Int] = service2()
for {
i <- service1Res
j <- service2Res
} yield i+j + 2
Many people say that actors are used best for holding state and futures for things like this. The problem you will encounter when modelling everything with actors is an explosion of messages you will need to define to communicate those actors.
If you really need or want to use actors when you have that handleAction message spawn a new actor that will complete the work and will get the a in c-tor. Additional benefit of this you will have nice supervision what is probably the least used options of akka and at the same time most valuable.