https://pulumi.com logo
Title
w

worried-knife-31967

03/11/2021, 11:24 AM
Unit testing against properties in an Apply with C#.... How do you do that? Assert's throw and exception, which is how the frameworks pick it up, but Exceptions in an Apply are swallowed. How do you get access to the value "outside" of the apply? or should I look at some kind of extension to extract the value outside the method and assert there?
@bored-oyster-3147 @tall-librarian-49374 any thoughts on this? As an example, I want to assert that there are 2 backendpools in a frontdoor instance...
var frontdoor = resources.OfType<Frontdoor>().FirstOrDefault();
            var pools = frontdoor.BackendPools;
Therefore I'm not sure how to access the ImmutableArray on that to check the size
Right now, I'm having to do:
var frontdoor = resources.OfType<Frontdoor>().FirstOrDefault();
            var backendPoolCount = 0;
            frontdoor.BackendPools.Apply(bp => {
                backendPoolCount = bp.Count();
                return false;
            });

            backendPoolCount.ShouldBe(1);
        }
which just feels dirty...
t

tall-librarian-49374

03/11/2021, 1:29 PM
w

worried-knife-31967

03/11/2021, 1:54 PM
glad you sent that, that was what I was about to build... would be better if it was supplied, but I can see that it would be abused in a real scenario...
l

little-cartoon-10569

03/11/2021, 8:01 PM
In .NET does that code work, @worried-knife-31967? In TS, it wouldn't: the code in the
Apply()
would happen asynchronously, and almost certainly after the
ShouldBe()
.
b

bored-oyster-3147

03/11/2021, 8:14 PM
Well it is a race condition but he is mocking all of the other resources so I don't think he actually had any asynchronous dependents so he might've just got lucky that his code was executing synchronously causing that use of
.Apply
to work for him
l

little-cartoon-10569

03/11/2021, 8:17 PM
There are libraries for async testing in Node. Hopefully there's similar support in .NET. The general pattern is to declare the test function async, and await the async code. Does that work in .NET?
b

bored-oyster-3147

03/11/2021, 8:18 PM
yea that is what Mikhail suggested
l

little-cartoon-10569

03/11/2021, 8:20 PM
Something like
[TestMethod]
public async Task CorrectlyFailingTest()
{
  var frontdoor = resources.OfType<Frontdoor>().FirstOrDefault();
  (await frontdoor.BackendPools.Apply(bp => {
    return bp.Count();
  })).GetValueAsync().ShouldBe(1);
}
Ah yes, I see in that link,
GetValueAsync()
. Good stuff. Updated previous comment.
b

bored-oyster-3147

03/11/2021, 8:29 PM
actually you don't use apply anymore you just await the output directly so:
var backendPools = await frontdoor.BackendPools.GetValueAsync();
var backendPoolCount = backendPools.Count();
l

little-cartoon-10569

03/11/2021, 8:32 PM
Nice. I want one of those for Node 🙂
t

tall-librarian-49374

03/11/2021, 8:52 PM
Here you go
const promise = <T>(output: pulumi.Output<T>): Promise<T | undefined> =>
  (output as any).promise() as Promise<T>;

it("should have a tag:key Name", async () => {
  const tags = await promise(vpc.tags);
  expect(tags).to.include.keys("Name");
  expect(tags?.Name).to.equal("my_app");
});
l

little-cartoon-10569

03/11/2021, 9:11 PM
I use Chai As Promised.
const promise = <T>(output: pulumi.Output<T>): Promise<T | undefined> =>
  (output as any).promise() as Promise<T>;

it("should have a tag:key Name", async () => {
  expect(vpc.tags).to.eventually.include.keys("Name");
  expect(vpc.tags?.Name).to.eventually.equal("my_app");
});
But it's not as nice as the .NET version. Something like
const promise = <T>(output: pulumi.Output<T>): Promise<T | undefined> =>
it("should have a tag:key Name", async () => {
  expect(vpc.tags.getAsyncValue()).to.include.keys("Name");
  expect(vpc.tags?.Name.getAsyncValue()).to.equal("my_app");
});
Or even
expectAsync(vpc.tags).to.include.keys("Name")
.. tidier still.